diff --git a/.eslintrc b/.eslintrc index f66c592e8..5b6e8f753 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,7 +2,7 @@ "env": { "browser": true, "commonjs": true, - "es6": true, + "es2021": true, "node": true, "jest": true }, @@ -11,26 +11,24 @@ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", - "prettier", - "prettier/@typescript-eslint" + "prettier" ], "plugins": [ "import" ], "parserOptions": { "project": "tsconfig.json", - "sourceType": "module", - "ecmaVersion": 2020 + "sourceType": "module" }, "rules": { "linebreak-style": ["error", "unix"], "no-empty": 1, - "no-undef": 0, "no-useless-catch": 1, "no-prototype-builtins": 1, "no-constant-condition": 0, "no-useless-escape" : 0, "no-console": "error", + "require-yield": 0, "eqeqeq": ["error", "smart"], "spaced-comment": [ "warn", @@ -121,6 +119,12 @@ "leadingUnderscore": "allow", "trailingUnderscore": "allowSingleOrDouble" }, + { + "selector": "function", + "format": ["camelCase", "PascalCase"], + "leadingUnderscore": "allow", + "trailingUnderscore": "allowSingleOrDouble" + }, { "selector": "variable", "format": ["camelCase", "UPPER_CASE", "PascalCase"], diff --git a/.npmignore b/.npmignore index 4a1857eea..3e70e24c7 100644 --- a/.npmignore +++ b/.npmignore @@ -14,3 +14,4 @@ /docs /benches /builds +/dist/tsbuildinfo diff --git a/default.nix b/default.nix index 79e7317a4..623b39dee 100644 --- a/default.nix +++ b/default.nix @@ -1,5 +1,6 @@ { runCommandNoCC , callPackage +, jq }: let @@ -11,20 +12,40 @@ let packageName = utils.node2nixDev.packageName; } '' - mkdir -p $out/lib/node_modules/${utils.node2nixDev.packageName} + mkdir -p "$out/lib/node_modules/${utils.node2nixDev.packageName}" # copy the package.json - cp ${utils.node2nixDev}/lib/node_modules/${utils.node2nixDev.packageName}/package.json $out/lib/node_modules/${utils.node2nixDev.packageName}/ + cp \ + "${utils.node2nixDev}/lib/node_modules/${utils.node2nixDev.packageName}/package.json" \ + "$out/lib/node_modules/${utils.node2nixDev.packageName}/" # copy the dist - cp -r ${utils.node2nixDev}/lib/node_modules/${utils.node2nixDev.packageName}/dist $out/lib/node_modules/${utils.node2nixDev.packageName}/ + cp -r \ + "${utils.node2nixDev}/lib/node_modules/${utils.node2nixDev.packageName}/dist" \ + "$out/lib/node_modules/${utils.node2nixDev.packageName}/" # copy over the production dependencies if [ -d "${utils.node2nixProd}/lib/node_modules" ]; then - cp -r ${utils.node2nixProd}/lib/node_modules $out/lib/node_modules/${utils.node2nixDev.packageName}/ + cp -r \ + "${utils.node2nixProd}/lib/node_modules" \ + "$out/lib/node_modules/${utils.node2nixDev.packageName}/" fi - # create symlink to the deployed executable folder, if applicable - if [ -d "${utils.node2nixDev}/lib/node_modules/.bin" ]; then - cp -r ${utils.node2nixDev}/lib/node_modules/.bin $out/lib/node_modules/ - ln -s $out/lib/node_modules/.bin $out/bin + # symlink bin executables + if [ \ + "$(${jq}/bin/jq 'has("bin")' "$out/lib/node_modules/${utils.node2nixDev.packageName}/package.json")" \ + == \ + "true" \ + ]; then + mkdir -p "$out/bin" + while IFS= read -r bin_name && IFS= read -r bin_path; do + # make files executable + chmod a+x "$out/lib/node_modules/${utils.node2nixDev.packageName}/$bin_path" + # create the symlink + ln -s \ + "../lib/node_modules/${utils.node2nixDev.packageName}/$bin_path" \ + "$out/bin/$bin_name" + done < <( + ${jq}/bin/jq -r 'select(.bin != null) | .bin | to_entries[] | (.key, .value)' \ + "$out/lib/node_modules/${utils.node2nixDev.packageName}/package.json" + ) fi - ''; + ''; in drv diff --git a/jest.config.js b/jest.config.js index 46fe908e2..f811716a8 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,7 @@ const os = require('os'); const path = require('path'); const fs = require('fs'); const process = require('process'); -const { pathsToModuleNameMapper } = require('ts-jest/utils'); +const { pathsToModuleNameMapper } = require('ts-jest'); const { compilerOptions } = require('./tsconfig'); const moduleNameMapper = pathsToModuleNameMapper( diff --git a/package-lock.json b/package-lock.json index eca4f5a4d..70219d0c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,117 +1,11769 @@ { "name": "@matrixai/polykey", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "@matrixai/polykey", + "version": "1.0.0", + "license": "GPL-3.0", + "dependencies": { + "@grpc/grpc-js": "1.6.7", + "@matrixai/async-init": "^1.7.3", + "@matrixai/async-locks": "^2.2.4", + "@matrixai/db": "^3.3.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/id": "^3.3.3", + "@matrixai/logger": "^2.1.1", + "@matrixai/resources": "^1.1.3", + "@matrixai/workers": "^1.3.3", + "ajv": "^7.0.4", + "bip39": "^3.0.3", + "canonicalize": "^1.0.5", + "cheerio": "^1.0.0-rc.5", + "commander": "^8.3.0", + "cross-fetch": "^3.0.6", + "cross-spawn": "^7.0.3", + "encryptedfs": "^3.5.1", + "fast-fuzzy": "^1.10.8", + "fd-lock": "^1.2.0", + "google-protobuf": "^3.14.0", + "ip-num": "^1.3.3-0", + "isomorphic-git": "^1.8.1", + "jose": "^4.3.6", + "lexicographic-integer": "^1.1.0", + "multiformats": "^9.4.8", + "node-forge": "^0.10.0", + "pako": "^1.0.11", + "prompts": "^2.4.1", + "readable-stream": "^3.6.0", + "resource-counter": "^1.2.4", + "threads": "^1.6.5", + "utp-native": "^2.5.3", + "uuid": "^8.3.0" + }, + "bin": { + "pk": "dist/bin/polykey.js", + "polykey": "dist/bin/polykey.js" + }, + "devDependencies": { + "@babel/preset-env": "^7.13.10", + "@types/cross-spawn": "^6.0.2", + "@types/google-protobuf": "^3.7.4", + "@types/jest": "^27.0.2", + "@types/nexpect": "^0.4.31", + "@types/node": "^16.11.7", + "@types/node-forge": "^0.9.7", + "@types/pako": "^1.0.2", + "@types/prompts": "^2.0.13", + "@types/readable-stream": "^2.3.11", + "@types/uuid": "^8.3.0", + "@typescript-eslint/eslint-plugin": "^5.23.0", + "@typescript-eslint/parser": "^5.23.0", + "babel-jest": "^27.0.0", + "eslint": "^8.15.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-prettier": "^4.0.0", + "grpc_tools_node_protoc_ts": "^5.1.3", + "jest": "^27.2.5", + "jest-mock-process": "^1.4.1", + "jest-mock-props": "^1.9.0", + "mocked-env": "^1.3.5", + "nexpect": "^0.6.0", + "node-gyp-build": "4.4.0", + "pkg": "5.6.0", + "prettier": "^2.6.2", + "ts-jest": "^27.0.5", + "ts-node": "^10.4.0", + "tsconfig-paths": "^3.9.0", + "typedoc": "^0.22.15", + "typescript": "^4.5.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", + "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.10.tgz", + "integrity": "sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.10", + "@babel/helper-compilation-targets": "^7.17.10", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.9", + "@babel/parser": "^7.17.10", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.10", + "@babel/types": "^7.17.10", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.10.tgz", + "integrity": "sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.10", + "@jridgewell/gen-mapping": "^0.1.0", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", + "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", + "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", + "dev": true, + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz", + "integrity": "sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.17.10", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.20.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.9.tgz", + "integrity": "sha512-kUjip3gruz6AJKOq5i3nC6CoCEEF/oHH3cp6tOZhB+IyyyPyW0g1Gfsxn3mkk6S08pIA2y8GQh609v9G/5sHVQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", + "@babel/helper-member-expression-to-functions": "^7.17.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", + "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "regexpu-core": "^5.0.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", + "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", + "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz", + "integrity": "sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", + "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", + "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", + "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-wrap-function": "^7.16.8", + "@babel/types": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", + "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", + "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", + "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.9", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", + "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.10.tgz", + "integrity": "sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", + "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", + "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", + "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", + "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz", + "integrity": "sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.17.6", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", + "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", + "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", + "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", + "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", + "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", + "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", + "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", + "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", + "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", + "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.10", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", + "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", + "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.10.tgz", + "integrity": "sha512-xJefea1DWXW09pW4Tm9bjwVlPDyYA2it3fWlmEjpYz6alPvTUjL0EOzNzI/FEOyI3r4/J7uVH5UqKgl1TQ5hqQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", + "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", + "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", + "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", + "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", + "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", + "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz", + "integrity": "sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", + "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", + "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", + "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", + "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", + "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", + "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", + "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", + "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz", + "integrity": "sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.17.8.tgz", + "integrity": "sha512-39reIkMTUVagzgA5x88zDYXPCMT6lcaRKs1+S9K6NKBPErbgO/w/kP8GlNQTC87b412ZTlmNgr3k2JrWgHH+Bw==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", + "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.10.tgz", + "integrity": "sha512-v54O6yLaJySCs6mGzaVOUw9T967GnH38T6CQSAtnzdNPwu84l2qAjssKzo/WSO8Yi7NF+7ekm5cVbF/5qiIgNA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", + "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", + "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", + "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", + "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz", + "integrity": "sha512-Lc2TfbxR1HOyn/c6b4Y/b6NHoTb67n/IoWLxTu4kC7h4KQnWlhCq2S8Tx0t2SVvv5Uu87Hs+6JEJ5kt2tYGylQ==", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.15.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", + "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", + "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", + "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", + "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", + "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", + "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", + "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", + "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.17.10.tgz", + "integrity": "sha512-YNgyBHZQpeoBSRBg0xixsZzfT58Ze1iZrajvv0lJc70qDDGuGfonEnMGfWeSY0mQ3JTuCWFbMkzFRVafOyJx4g==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.17.10", + "@babel/helper-compilation-targets": "^7.17.10", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-async-generator-functions": "^7.16.8", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.17.6", + "@babel/plugin-proposal-dynamic-import": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.16.7", + "@babel/plugin-proposal-json-strings": "^7.16.7", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-numeric-separator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.17.3", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-private-methods": "^7.16.11", + "@babel/plugin-proposal-private-property-in-object": "^7.16.7", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.16.7", + "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-block-scoped-functions": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.16.7", + "@babel/plugin-transform-classes": "^7.16.7", + "@babel/plugin-transform-computed-properties": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.17.7", + "@babel/plugin-transform-dotall-regex": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-exponentiation-operator": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-function-name": "^7.16.7", + "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-member-expression-literals": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.17.9", + "@babel/plugin-transform-modules-systemjs": "^7.17.8", + "@babel/plugin-transform-modules-umd": "^7.16.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.17.10", + "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-object-super": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-property-literals": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.17.9", + "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-shorthand-properties": "^7.16.7", + "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-sticky-regex": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.16.7", + "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-unicode-escapes": "^7.16.7", + "@babel/plugin-transform-unicode-regex": "^7.16.7", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.17.10", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.22.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", + "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.10.tgz", + "integrity": "sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.10", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.10", + "@babel/types": "^7.17.10", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.10.tgz", + "integrity": "sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", + "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.9.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz", + "integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==", + "dependencies": { + "@grpc/proto-loader": "^0.6.4", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.12.tgz", + "integrity": "sha512-filTVbETFnxb9CyRX98zN18ilChTuf/C5scZ2xyaOTp0EHGq0/ufX8rjqXUcSb1Gpv7eZq4M2jDvbh9BogKnrg==", + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.10.0", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", + "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", + "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", + "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", + "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@matrixai/async-init": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@matrixai/async-init/-/async-init-1.7.3.tgz", + "integrity": "sha512-Sf3q5ODhVJqrYiAdGXmwj606956lgEMKGM9LMFU5scIOh13WokHo3GthjB1yh/umCV75NYvHJn60R9gnudVZ3Q==", + "dependencies": { + "@matrixai/async-locks": "^2.2.4", + "@matrixai/errors": "^1.1.1" + } + }, + "node_modules/@matrixai/async-locks": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.2.4.tgz", + "integrity": "sha512-AEGQMM7zw8Mkcc0hbNpOCNKa6DW+04rVIwyZgUnPWawPqwUt5HSGaQwdXI3dXO+35G/vjJppggv+JJZsGfEjvA==", + "dependencies": { + "@matrixai/errors": "^1.1.1", + "@matrixai/resources": "^1.1.3", + "async-mutex": "^0.3.2" + } + }, + "node_modules/@matrixai/db": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.3.3.tgz", + "integrity": "sha512-7yu3Cl/euV4CKs/2InuynbTtStAGankL1hkGZq3+oiO7Z3RN69sQ/pA2EOWD/W4+xeG+q1iTDP8H5e4oy2DXMA==", + "dependencies": { + "@matrixai/async-init": "^1.7.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/logger": "^2.1.1", + "@matrixai/resources": "^1.1.3", + "@matrixai/workers": "^1.3.3", + "@types/abstract-leveldown": "^7.2.0", + "level": "7.0.1", + "threads": "^1.6.5" + } + }, + "node_modules/@matrixai/errors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.1.1.tgz", + "integrity": "sha512-ywhDblmPCfJCt3JTD8PB6rzREZ/Ex4UoLEGLw3fALhGV2AsU7NMax801PtsqbZcOfNEs2uOa1wqyhqyn3L8s9g==", + "dependencies": { + "ts-custom-error": "^3.2.0" + } + }, + "node_modules/@matrixai/id": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@matrixai/id/-/id-3.3.3.tgz", + "integrity": "sha512-eXkxv68sCT17f6XQU8zMwgLLqwbdFm+8DoL3gXfBqfiDYxOCCQBS4L9kjUby8gRdlP7mIpkJ6oVAWCUnykGInA==", + "dependencies": { + "multiformats": "^9.4.8", + "uuid": "^8.3.2" + } + }, + "node_modules/@matrixai/logger": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@matrixai/logger/-/logger-2.1.1.tgz", + "integrity": "sha512-79KM0PyJTpfkALf9DK2xGniU+9gngsb5O8hcdUviWz+zR2W0hnTQq/g7tJW0YnIEhmDe/GkJf0Bnbs+gWfj3BA==" + }, + "node_modules/@matrixai/resources": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@matrixai/resources/-/resources-1.1.3.tgz", + "integrity": "sha512-9zbA0NtgCtA+2hILpojshH6Pd679bIPtB8DcsPLVDzvGZP1TDwvtvZWCC3SG7oJUTzxqBI2Bfe+hypqwpvYPCw==" + }, + "node_modules/@matrixai/workers": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.3.3.tgz", + "integrity": "sha512-ID1sSJDXjM0hdWC10euWGcFofuys7+IDP+XTBh8Gq6jirn18xJs71wSy357qxLVSa7mL00qRJJfW6rljcFUK4A==", + "dependencies": { + "@matrixai/async-init": "^1.7.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/logger": "^2.1.1", + "threads": "^1.6.5" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@types/abstract-leveldown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", + "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==" + }, + "node_modules/@types/babel__core": { + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.17.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", + "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/cross-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", + "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/google-protobuf": { + "version": "3.15.6", + "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.6.tgz", + "integrity": "sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==", + "dev": true + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-fUy7YRpT+rHXto1YlL+J9rs0uLGyiqVt3ZOTQR+4ROc47yNl8WLdVLgUloBRhOxP1PZvguHl44T3H0wAWxahYQ==", + "dev": true, + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/nexpect": { + "version": "0.4.31", + "resolved": "https://registry.npmjs.org/@types/nexpect/-/nexpect-0.4.31.tgz", + "integrity": "sha512-Plh9Dlj2AKdsblgF1Pv7s2BjlojqW93d1zIUtK5xVVrUjkZQezyWIOAq0Xfwp0e0SDQ70YmaDqzhoJru2kqVPA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "16.11.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.35.tgz", + "integrity": "sha512-QXu45LyepgnhUfnIAj/FyT4uM87ug5KpIrgXfQtUPNAlx8w5hmd8z8emqCLNvG11QkpRSCG9Qg2buMxvqfjfsQ==" + }, + "node_modules/@types/node-forge": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-0.9.10.tgz", + "integrity": "sha512-+BbPlhZeYs/WETWftQi2LeRx9VviWSwawNo+Pid5qNrSZHb60loYjpph3OrbwXMMseadu9rE9NeK34r4BHT+QQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/pako": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.4.tgz", + "integrity": "sha512-Z+5bJSm28EXBSUJEgx29ioWeEEHUh6TiMkZHDhLwjc9wVFH+ressbkmX6waUZc5R3Gobn4Qu5llGxaoflZ+yhA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.1.tgz", + "integrity": "sha512-XFjFHmaLVifrAKaZ+EKghFHtHSUonyw8P2Qmy2/+osBnrKbH9UYtlK10zg8/kCt47MFilll/DEDKy3DHfJ0URw==", + "dev": true + }, + "node_modules/@types/prompts": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.14.tgz", + "integrity": "sha512-HZBd99fKxRWpYCErtm2/yxUZv6/PBI9J7N4TNFffl5JbrYMHBwF25DjQGTW3b3jmXq+9P6/8fCIb2ee57BFfYA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/readable-stream": { + "version": "2.3.13", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.13.tgz", + "integrity": "sha512-4JSCx8EUzaW9Idevt+9lsRAt1lcSccoQfE+AouM1gk8sFxnnytKNIO3wTl9Dy+4m6jRJ1yXhboLHHT/LXBQiEw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "safe-buffer": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.23.0.tgz", + "integrity": "sha512-hEcSmG4XodSLiAp1uxv/OQSGsDY6QN3TcRU32gANp+19wGE1QQZLRS8/GV58VRUoXhnkuJ3ZxNQ3T6Z6zM59DA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/type-utils": "5.23.0", + "@typescript-eslint/utils": "5.23.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.23.0.tgz", + "integrity": "sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.23.0.tgz", + "integrity": "sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.23.0.tgz", + "integrity": "sha512-iuI05JsJl/SUnOTXA9f4oI+/4qS/Zcgk+s2ir+lRmXI+80D8GaGwoUqs4p+X+4AxDolPpEpVUdlEH4ADxFy4gw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.23.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.23.0.tgz", + "integrity": "sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.23.0.tgz", + "integrity": "sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.23.0.tgz", + "integrity": "sha512-dbgaKN21drqpkbbedGMNPCtRPZo1IOUr5EI9Jrrh99r5UW5Q0dz46RKXeSBoPV+56R6dFKpbrdhgUNSJsDDRZA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.23.0.tgz", + "integrity": "sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.23.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "node_modules/abstract-leveldown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", + "integrity": "sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ==", + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.0.0", + "is-buffer": "^2.0.5", + "level-concat-iterator": "^3.0.0", + "level-supports": "^2.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.4.tgz", + "integrity": "sha512-nBeQgg/ZZA3u3SYxyaDvpvDtgZ/EZPF547ARgZBrG9Bhu1vKDwAIjtIf+sDtJUKa2zOcEbmRLBRSyMraS/Oy1A==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "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/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/are-we-there-yet/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, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-lock": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.1.tgz", + "integrity": "sha512-zK7xap9UnttfbE23JmcrNIyueAn6jWshihJqA33U/hEnKprF/lVGBDsBv/bqLm2YMMl1DnpHhUY044eA0t1TUw==" + }, + "node_modules/async-mutex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", + "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", + "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.3.1", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", + "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.1", + "core-js-compat": "^3.21.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", + "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-runtime/node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bip39": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", + "integrity": "sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==", + "dependencies": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + } + }, + "node_modules/bip39/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + }, + "node_modules/bitset": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bitset/-/bitset-5.1.1.tgz", + "integrity": "sha512-oKaRp6mzXedJ1Npo86PKhWfDelI6HxxJo+it9nAcBB0HLVvYVp+5i6yj6DT5hfFgo+TS5T57MRWtw8zhwdTs3g==", + "engines": { + "node": "*" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", + "escalade": "^3.1.1", + "node-releases": "^2.0.3", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001340", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001340.tgz", + "integrity": "sha512-jUNz+a9blQTQVu4uFcn17uAD8IDizPzQkIKh3LCJfg9BkyIqExYYdyc/ZSlWUSKb8iYiXxKsxbv4zYSvkqjrxw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/canonicalize": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.8.tgz", + "integrity": "sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==" + }, + "node_modules/catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dependencies": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", + "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", + "dependencies": { + "css-select": "^4.3.0", + "css-what": "^6.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.3.1", + "domutils": "^2.8.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/ci-info": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "dev": true + }, + "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==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/clean-git-ref": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", + "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==" + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true + }, + "node_modules/core-js-compat": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.5.tgz", + "integrity": "sha512-rEF75n3QtInrYICvJjrAgV03HwKiYvtKHdPtaba1KucG+cNZ4NJnH9isqt979e67KZlhpbCOTwnsvnIr+CVeOg==", + "dev": true, + "dependencies": { + "browserslist": "^4.20.3", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "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==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "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==", + "dev": true + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "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": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deferred-leveldown": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-7.0.0.tgz", + "integrity": "sha512-QKN8NtuS3BC6m0B8vAnBls44tX1WXAFATUsJlruyAYbZpysWV3siH6o/i3g9DCHauzodksO60bdj5NazNbjCmg==", + "dependencies": { + "abstract-leveldown": "^7.2.0", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/diff3": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", + "integrity": "sha1-1OXDpM305f4SEatC5pP8tDIVgPw=" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "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/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encoding-down": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-7.1.0.tgz", + "integrity": "sha512-ky47X5jP84ryk5EQmvedQzELwVJPjCgXDQZGeb9F6r4PdChByCGHTBrVcF3h8ynKVJ1wVbkxTsDC8zBROPypgQ==", + "dependencies": { + "abstract-leveldown": "^7.2.0", + "inherits": "^2.0.3", + "level-codec": "^10.0.0", + "level-errors": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/encryptedfs": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.1.tgz", + "integrity": "sha512-gGyL8Ax61WAte3ABiz26WuFSIhEmTh0KcGfugkQunpdcEKoex/3T+2l6InCv35VSFAQ/l5vbBFAYFdKT15JL2w==", + "dependencies": { + "@matrixai/async-init": "^1.7.3", + "@matrixai/async-locks": "^2.2.4", + "@matrixai/db": "3.3.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/logger": "^2.1.1", + "@matrixai/resources": "^1.1.3", + "@matrixai/workers": "^1.3.3", + "errno": "^0.1.7", + "lexicographic-integer": "^1.1.0", + "node-forge": "^1.3.1", + "readable-stream": "^3.6.0", + "resource-counter": "^1.2.4", + "threads": "^1.6.5", + "util-callbackify": "^1.0.0" + } + }, + "node_modules/encryptedfs/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/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/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/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.0.tgz", + "integrity": "sha512-URbD8tgRthKD3YcC39vbvSDrX23upXnPcnGAjQfgxXF5ID75YcENawc9ZX/9iTP9ptUyfCLIxTTuMYoRfiOVKA==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.1", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "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==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", + "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.2.3", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-prettier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/espree": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "dev": true, + "dependencies": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-fuzzy": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fast-fuzzy/-/fast-fuzzy-1.11.1.tgz", + "integrity": "sha512-FaO8kAsdAqV0SOBbLelpuBNar4C6lUS82OqDlM6Y/I0Q9joMmxAxll8AMrfTLp82rRuZj/2+BzFZgOHA18vN6A==", + "dependencies": { + "graphemesplit": "^2.4.1" + } + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-lock": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fd-lock/-/fd-lock-1.2.0.tgz", + "integrity": "sha512-Lk/pKH2DldLpG4Yh/sOOY84k5VqNzxHPffGwf1+yYI+/qMXzTPp9KJMX+Wh6n4xqGSA1Mu7JPmaDArfJGw2O/A==", + "hasInstallScript": true, + "dependencies": { + "napi-macros": "^2.0.0", + "node-gyp-build": "^4.2.2" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/from2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "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/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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/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/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/google-protobuf": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.20.1.tgz", + "integrity": "sha512-XMf1+O32FjYIV3CYu6Tuh5PNbfNEU5Xu22X+Xkdb/DUexFlCzhvv7d5Iirm4AOwn8lv4al1YvIhzGrg2j9Zfzw==" + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/graphemesplit": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/graphemesplit/-/graphemesplit-2.4.4.tgz", + "integrity": "sha512-lKrpp1mk1NH26USxC/Asw4OHbhSQf5XfrWZ+CDv/dFVvd1j17kFgMotdJvOesmHkbFX9P9sBfpH8VogxOWLg8w==", + "dependencies": { + "js-base64": "^3.6.0", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/grpc_tools_node_protoc_ts": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/grpc_tools_node_protoc_ts/-/grpc_tools_node_protoc_ts-5.3.2.tgz", + "integrity": "sha512-7xPSeu8bwjcird3i9R5+9O4BF2Lhv9fMBdeobfUc2Bys9tSVtm/VB3WjTpKV78WlLYJyD94+wL/8hJqaMZ53Hw==", + "dev": true, + "dependencies": { + "google-protobuf": "3.15.8", + "handlebars": "4.7.7" + }, + "bin": { + "protoc-gen-ts": "bin/protoc-gen-ts" + } + }, + "node_modules/grpc_tools_node_protoc_ts/node_modules/google-protobuf": { + "version": "3.15.8", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", + "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "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" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "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==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/into-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", + "dev": true, + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ip-num": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ip-num/-/ip-num-1.4.0.tgz", + "integrity": "sha512-MP+gq4uBvrvm+G7EwP14GcJeFK49/p6sZrNOarMUoExLRodULJQM8mnkb/SbT1YKxRsZfh8rgwei2pUJIa35jA==" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-observable": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", + "integrity": "sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/isomorphic-git": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.17.2.tgz", + "integrity": "sha512-KtYyJye7Ad1XSgObsw7dwn3OaEcGUy04BHv6D+qBz2BWY7T7q7HXBzoSOiVvVMbOo+K2EZ2MUT+g2QkpJCPQLQ==", + "dependencies": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", + "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dev": true, + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dev": true, + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-jasmine2/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-mock-process": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jest-mock-process/-/jest-mock-process-1.4.1.tgz", + "integrity": "sha512-ZZUKRlEBizutngoO4KngzN30YoeAYP3nnwimk4cpi9WqLxQUf6SlAPK5p1D9usEpxDS3Uif2MIez3Bq0vGYR+g==", + "dev": true, + "peerDependencies": { + "jest": ">=23.4 <28" + } + }, + "node_modules/jest-mock-props": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/jest-mock-props/-/jest-mock-props-1.9.1.tgz", + "integrity": "sha512-PvTySOTw/K4dwL7XrVGq/VUZRm/qXPrV4+NuhgxuWkmE3h/Fd+g+qB0evK5vSBAkI8TaxvTXYv17IdxWdEze1g==", + "dev": true, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "jest": ">=24.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jose": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.8.1.tgz", + "integrity": "sha512-+/hpTbRcCw9YC0TOfN1W47pej4a9lRmltdOVdRLz5FP5UvUq3CenhXjQK7u/8NdMIIShMXYAh9VLPhc7TjhvFw==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-base64": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-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==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, + "node_modules/level": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level/-/level-7.0.1.tgz", + "integrity": "sha512-w3E64+ALx2eZf8RV5JL4kIcE0BFAvQscRYd1yU4YVqZN9RGTQxXSvH202xvK15yZwFFxRXe60f13LJjcJ//I4Q==", + "dependencies": { + "level-js": "^6.1.0", + "level-packager": "^6.0.1", + "leveldown": "^6.1.0" + }, + "engines": { + "node": ">=10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-codec": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-10.0.0.tgz", + "integrity": "sha512-QW3VteVNAp6c/LuV6nDjg7XDXx9XHK4abmQarxZmlRSDyXYk20UdaJTSX6yzVvQ4i0JyWSB7jert0DsyD/kk6g==", + "dependencies": { + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/level-concat-iterator": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz", + "integrity": "sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ==", + "dependencies": { + "catering": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/level-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-3.0.1.tgz", + "integrity": "sha512-tqTL2DxzPDzpwl0iV5+rBCv65HWbHp6eutluHNcVIftKZlQN//b6GEnZDM2CvGZvzGYMwyPtYppYnydBQd2SMQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/level-iterator-stream": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-5.0.0.tgz", + "integrity": "sha512-wnb1+o+CVFUDdiSMR/ZymE2prPs3cjVLlXuDeSq9Zb8o032XrabGEXcTCsBxprAtseO3qvFeGzh6406z9sOTRA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/level-js": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/level-js/-/level-js-6.1.0.tgz", + "integrity": "sha512-i7mPtkZm68aewfv0FnIUWvFUFfoyzIvVKnUmuQGrelEkP72vSPTaA1SGneWWoCV5KZJG4wlzbJLp1WxVNGuc6A==", + "dependencies": { + "abstract-leveldown": "^7.2.0", + "buffer": "^6.0.3", + "inherits": "^2.0.3", + "ltgt": "^2.1.2", + "run-parallel-limit": "^1.1.0" + } + }, + "node_modules/level-packager": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-6.0.1.tgz", + "integrity": "sha512-8Ezr0XM6hmAwqX9uu8IGzGNkWz/9doyPA8Oo9/D7qcMI6meJC+XhIbNYHukJhIn8OGdlzQs/JPcL9B8lA2F6EQ==", + "dependencies": { + "encoding-down": "^7.1.0", + "levelup": "^5.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/level-supports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-2.1.0.tgz", + "integrity": "sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/leveldown": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-6.1.1.tgz", + "integrity": "sha512-88c+E+Eizn4CkQOBHwqlCJaTNEjGpaEIikn1S+cINc5E9HEvJ77bqY4JY/HxT5u0caWqsc3P3DcFIKBI1vHt+A==", + "hasInstallScript": true, + "dependencies": { + "abstract-leveldown": "^7.2.0", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/levelup": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-5.1.1.tgz", + "integrity": "sha512-0mFCcHcEebOwsQuk00WJwjLI6oCjbBuEYdh/RaRqhjnyVlzqf41T1NnDtCedumZ56qyIh8euLFDqV1KfzTAVhg==", + "dependencies": { + "catering": "^2.0.0", + "deferred-leveldown": "^7.0.0", + "level-errors": "^3.0.1", + "level-iterator-stream": "^5.0.0", + "level-supports": "^2.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lexicographic-integer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/lexicographic-integer/-/lexicographic-integer-1.1.0.tgz", + "integrity": "sha1-UsptmYpXLmMitRX1uA45bGBD6bg=" + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/marked": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.15.tgz", + "integrity": "sha512-esX5lPdTfG4p8LDkv+obbRCyOKzB+820ZZyMOXJZygZBHrH9b3xXR64X4kT3sPe9Nx8qQXbmcz6kFSMt4Nfk6Q==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "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/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/minimisted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz", + "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==", + "dependencies": { + "minimist": "^1.2.5" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/mocked-env": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/mocked-env/-/mocked-env-1.3.5.tgz", + "integrity": "sha512-GyYY6ynVOdEoRlaGpaq8UYwdWkvrsU2xRme9B+WPSuJcNjh17+3QIxSYU6zwee0SbehhV6f06VZ4ahjG+9zdrA==", + "dev": true, + "dependencies": { + "check-more-types": "2.24.0", + "debug": "4.3.2", + "lazy-ass": "1.6.0", + "ramda": "0.27.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocked-env/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multiformats": { + "version": "9.6.5", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.6.5.tgz", + "integrity": "sha512-vMwf/FUO+qAPvl3vlSZEgEVFY/AxeZq5yg761ScF3CZsXgmTi/HGkicUiNN0CI4PW8FiY2P0OLklOcmQjdQJhw==" + }, + "node_modules/multistream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", + "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "once": "^1.4.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, + "node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/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==", + "dev": true + }, + "node_modules/nexpect": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/nexpect/-/nexpect-0.6.0.tgz", + "integrity": "sha512-gG4cO0zoNG+kaPesw516hPVEKLW3YizGU8UWMr5lpkHKOgoTWcu4sPQN7rWVAIL4Ck87zM4N8immPUhYPdDz3g==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.5" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nexpect/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==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/nexpect/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nexpect/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nexpect/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nexpect/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nexpect/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-abi": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "dev": true, + "dependencies": { + "semver": "^5.4.1" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/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/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", + "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "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.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", + "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/observable-fns": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/observable-fns/-/observable-fns-0.6.1.tgz", + "integrity": "sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/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/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.6.0.tgz", + "integrity": "sha512-mHrAVSQWmHA41RnUmRpC7pK9lNnMfdA16CF3cqOI22a8LZxOQzF7M8YWtA2nfs+d7I0MTDXOtkDsAsFXeCpYjg==", + "dev": true, + "dependencies": { + "@babel/parser": "7.16.2", + "@babel/types": "7.16.0", + "chalk": "^4.1.2", + "escodegen": "^2.0.0", + "fs-extra": "^9.1.0", + "globby": "^11.0.4", + "into-stream": "^6.0.0", + "minimist": "^1.2.5", + "multistream": "^4.1.0", + "pkg-fetch": "3.3.0", + "prebuild-install": "6.1.4", + "progress": "^2.0.3", + "resolve": "^1.20.0", + "stream-meter": "^1.0.4", + "tslib": "2.3.1" + }, + "bin": { + "pkg": "lib-es5/bin.js" + }, + "peerDependencies": { + "node-notifier": ">=9.0.1" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-fetch": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.3.0.tgz", + "integrity": "sha512-xJnIZ1KP+8rNN+VLafwu4tEeV4m8IkFBDdCFqmAJz9K1aiXEtbARmdbEe6HlXWGSVuShSHjFXpfkKRkDBQ5kiA==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "fs-extra": "^9.1.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.6", + "progress": "^2.0.3", + "semver": "^7.3.5", + "tar-fs": "^2.1.1", + "yargs": "^16.2.0" + }, + "bin": { + "pkg-fetch": "lib-es5/bin.js" + } + }, + "node_modules/pkg-fetch/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pkg-fetch/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/pkg-fetch/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/pkg-fetch/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/pkg-fetch/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-fetch/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pkg-fetch/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg/node_modules/@babel/parser": { + "version": "7.16.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz", + "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pkg/node_modules/@babel/types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/pkg/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pkg/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/pkg/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/pkg/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/pkg/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/prebuild-install": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "dev": true, + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.21.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prebuild-install/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prebuild-install/node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install/node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", + "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", + "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/resource-counter": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/resource-counter/-/resource-counter-1.2.4.tgz", + "integrity": "sha512-DGJChvE5r4smqPE+xYNv9r1u/I9cCfRR5yfm7D6EQckdKqMyVpJ5z0s40yn0EM0puFxHg6mPORrQLQdEbJ/RnQ==", + "dependencies": { + "babel-runtime": "^6.26.0", + "bitset": "^5.0.3" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "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", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.0.0", + "vscode-oniguruma": "^1.6.1", + "vscode-textmate": "5.2.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "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/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stream-meter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", + "integrity": "sha1-Uq+Vql6nYKJJFxZwTb/5D3Ov3R0=", + "dev": true, + "dependencies": { + "readable-stream": "^2.1.4" + } + }, + "node_modules/stream-meter/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "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-meter/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/stream-meter/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, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/threads": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/threads/-/threads-1.7.0.tgz", + "integrity": "sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==", + "dependencies": { + "callsites": "^3.1.0", + "debug": "^4.2.0", + "is-observable": "^2.1.0", + "observable-fns": "^0.6.1" + }, + "funding": { + "url": "https://github.com/andywer/threads.js?sponsor=1" + }, + "optionalDependencies": { + "tiny-worker": ">= 2" + } + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/timeout-refresh": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/timeout-refresh/-/timeout-refresh-1.0.3.tgz", + "integrity": "sha512-Mz0CX4vBGM5lj8ttbIFt7o4ZMxk/9rgudJRh76EvB7xXZMur7T/cjRiH2w4Fmkq0zxf2QpM8IFvOSRn8FEu3gA==" + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" + }, + "node_modules/tiny-worker": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tiny-worker/-/tiny-worker-2.3.0.tgz", + "integrity": "sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==", + "optional": true, + "dependencies": { + "esm": "^3.2.25" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-custom-error": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.2.0.tgz", + "integrity": "sha512-cBvC2QjtvJ9JfWLvstVnI45Y46Y5dMxIaG1TDMGAD/R87hpvqFL+7LhvUDhnRCfOnx/xitollFWWvUKKKhbN0A==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ts-jest": { + "version": "27.1.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.4.tgz", + "integrity": "sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@types/jest": "^27.0.0", + "babel-jest": ">=27.0.0 <28", + "jest": "^27.0.0", + "typescript": ">=3.8 <5.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + }, + "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/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typedoc": { + "version": "0.22.15", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.15.tgz", + "integrity": "sha512-CMd1lrqQbFvbx6S9G6fL4HKp3GoIuhujJReWqlIvSb2T26vGai+8Os3Mde7Pn832pXYemd9BMuuYWhFpL5st0Q==", + "dev": true, + "dependencies": { + "glob": "^7.2.0", + "lunr": "^2.3.9", + "marked": "^4.0.12", + "minimatch": "^5.0.1", + "shiki": "^0.10.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 12.10.0" + }, + "peerDependencies": { + "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typescript": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uglify-js": { + "version": "3.15.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", + "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-trie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "dependencies": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, + "node_modules/unicode-trie/node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=" + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unordered-set": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unordered-set/-/unordered-set-2.0.1.tgz", + "integrity": "sha512-eUmNTPzdx+q/WvOHW0bgGYLWvWHNT3PTKEQLg0MAQhc0AHASHVHoP/9YytYd4RBVariqno/mEUhVZN98CmD7bg==" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-callbackify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util-callbackify/-/util-callbackify-1.0.0.tgz", + "integrity": "sha512-5vEPPSM6DCHlCpq9FZryeIkY5FQMUqXLUz4yHtU369Z/abWUVdgInPVeINjWJV3Bk9DZhCr+JzGarEByPLsxBQ==", + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utp-native": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/utp-native/-/utp-native-2.5.3.tgz", + "integrity": "sha512-sWTrWYXPhhWJh+cS2baPzhaZc89zwlWCfwSthUjGhLkZztyPhcQllo+XVVCbNGi7dhyRlxkWxN4NKU6FbA9Y8w==", + "hasInstallScript": true, + "dependencies": { + "napi-macros": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.0.2", + "timeout-refresh": "^1.0.0", + "unordered-set": "^2.0.1" + }, + "bin": { + "ucat": "ucat.js" + }, + "engines": { + "node": ">=8.12" + } + }, + "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/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8-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==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", + "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", + "dev": true + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "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/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "requires": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.7" } }, "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", + "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", "dev": true }, "@babel/core": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.10.tgz", + "integrity": "sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.10", + "@babel/helper-compilation-targets": "^7.17.10", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.9", + "@babel/parser": "^7.17.10", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.10", + "@babel/types": "^7.17.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "json5": "^2.2.1", + "semver": "^6.3.0" } }, "@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.10.tgz", + "integrity": "sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg==", "dev": true, "requires": { - "@babel/types": "^7.15.6", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.17.10", + "@jridgewell/gen-mapping": "^0.1.0", + "jsesc": "^2.5.1" } }, "@babel/helper-annotate-as-pure": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", - "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", + "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz", - "integrity": "sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", + "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-explode-assignable-expression": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz", + "integrity": "sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "@babel/compat-data": "^7.17.10", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.20.2", "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", - "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.9.tgz", + "integrity": "sha512-kUjip3gruz6AJKOq5i3nC6CoCEEF/oHH3cp6tOZhB+IyyyPyW0g1Gfsxn3mkk6S08pIA2y8GQh609v9G/5sHVQ==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", + "@babel/helper-member-expression-to-functions": "^7.17.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", - "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", + "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "regexpu-core": "^4.7.1" + "@babel/helper-annotate-as-pure": "^7.16.7", + "regexpu-core": "^5.0.1" } }, "@babel/helper-define-polyfill-provider": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", - "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.13.0", @@ -124,362 +11776,371 @@ "semver": "^6.1.2" } }, - "@babel/helper-explode-assignable-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz", - "integrity": "sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g==", + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, - "@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "@babel/helper-explode-assignable-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", + "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, - "@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "@babel/helper-function-name": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", + "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/template": "^7.16.7", + "@babel/types": "^7.17.0" } }, "@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz", + "integrity": "sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.17.0" } }, "@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", + "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" } }, "@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", + "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz", - "integrity": "sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", + "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-wrap-function": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-wrap-function": "^7.16.8", + "@babel/types": "^7.16.8" } }, "@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", + "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.17.0" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", - "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", "dev": true }, "@babel/helper-wrap-function": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz", - "integrity": "sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", + "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-function-name": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8" } }, "@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", + "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", "dev": true, "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.9", + "@babel/types": "^7.17.0" } }, "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", + "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.10.tgz", + "integrity": "sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==", "dev": true }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", + "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7" + } + }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz", - "integrity": "sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", + "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", - "@babel/plugin-proposal-optional-chaining": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.7" } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz", - "integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", + "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.15.4", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", - "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", + "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz", - "integrity": "sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA==", + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz", + "integrity": "sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-create-class-features-plugin": "^7.17.6", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", - "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", + "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", - "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", + "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", - "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", + "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", - "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", + "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", - "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", + "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", - "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", + "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz", - "integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==", + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz", + "integrity": "sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==", "dev": true, "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/compat-data": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.15.4" + "@babel/plugin-transform-parameters": "^7.16.7" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", - "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", + "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", - "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", + "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", - "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", + "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.16.10", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz", - "integrity": "sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", + "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", - "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", + "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-async-generators": { @@ -623,347 +12284,359 @@ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.10.tgz", + "integrity": "sha512-xJefea1DWXW09pW4Tm9bjwVlPDyYA2it3fWlmEjpYz6alPvTUjL0EOzNzI/FEOyI3r4/J7uVH5UqKgl1TQ5hqQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", - "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", + "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", - "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", + "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.14.5" + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", - "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", + "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", - "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", + "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-classes": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz", - "integrity": "sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", + "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", - "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", + "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-destructuring": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", - "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz", + "integrity": "sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", - "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", + "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", - "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", + "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", - "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", + "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-for-of": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz", - "integrity": "sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", + "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", - "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", + "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", - "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", + "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", - "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", + "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", - "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", + "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", - "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz", + "integrity": "sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", - "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.17.8.tgz", + "integrity": "sha512-39reIkMTUVagzgA5x88zDYXPCMT6lcaRKs1+S9K6NKBPErbgO/w/kP8GlNQTC87b412ZTlmNgr3k2JrWgHH+Bw==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", - "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", + "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", - "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.10.tgz", + "integrity": "sha512-v54O6yLaJySCs6mGzaVOUw9T967GnH38T6CQSAtnzdNPwu84l2qAjssKzo/WSO8Yi7NF+7ekm5cVbF/5qiIgNA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.17.0" } }, "@babel/plugin-transform-new-target": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", - "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", + "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-object-super": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", - "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", + "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7" } }, "@babel/plugin-transform-parameters": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz", - "integrity": "sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", + "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-property-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", - "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", + "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-regenerator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", - "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz", + "integrity": "sha512-Lc2TfbxR1HOyn/c6b4Y/b6NHoTb67n/IoWLxTu4kC7h4KQnWlhCq2S8Tx0t2SVvv5Uu87Hs+6JEJ5kt2tYGylQ==", "dev": true, "requires": { - "regenerator-transform": "^0.14.2" + "regenerator-transform": "^0.15.0" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", - "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", + "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", - "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", + "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-spread": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz", - "integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", + "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", - "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", + "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-template-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", - "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", + "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", - "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", + "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", - "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", + "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", - "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", + "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/preset-env": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.8.tgz", - "integrity": "sha512-rCC0wH8husJgY4FPbHsiYyiLxSY8oMDJH7Rl6RQMknbN9oDDHhM9RDFvnGM2MgkbUJzSQB4gtuwygY5mCqGSsA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4", - "@babel/plugin-proposal-async-generator-functions": "^7.15.8", - "@babel/plugin-proposal-class-properties": "^7.14.5", - "@babel/plugin-proposal-class-static-block": "^7.15.4", - "@babel/plugin-proposal-dynamic-import": "^7.14.5", - "@babel/plugin-proposal-export-namespace-from": "^7.14.5", - "@babel/plugin-proposal-json-strings": "^7.14.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", - "@babel/plugin-proposal-numeric-separator": "^7.14.5", - "@babel/plugin-proposal-object-rest-spread": "^7.15.6", - "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", - "@babel/plugin-proposal-optional-chaining": "^7.14.5", - "@babel/plugin-proposal-private-methods": "^7.14.5", - "@babel/plugin-proposal-private-property-in-object": "^7.15.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.17.10.tgz", + "integrity": "sha512-YNgyBHZQpeoBSRBg0xixsZzfT58Ze1iZrajvv0lJc70qDDGuGfonEnMGfWeSY0mQ3JTuCWFbMkzFRVafOyJx4g==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.17.10", + "@babel/helper-compilation-targets": "^7.17.10", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-async-generator-functions": "^7.16.8", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.17.6", + "@babel/plugin-proposal-dynamic-import": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.16.7", + "@babel/plugin-proposal-json-strings": "^7.16.7", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-numeric-separator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.17.3", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-private-methods": "^7.16.11", + "@babel/plugin-proposal-private-property-in-object": "^7.16.7", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", @@ -978,51 +12651,51 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.14.5", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/plugin-transform-block-scoped-functions": "^7.14.5", - "@babel/plugin-transform-block-scoping": "^7.15.3", - "@babel/plugin-transform-classes": "^7.15.4", - "@babel/plugin-transform-computed-properties": "^7.14.5", - "@babel/plugin-transform-destructuring": "^7.14.7", - "@babel/plugin-transform-dotall-regex": "^7.14.5", - "@babel/plugin-transform-duplicate-keys": "^7.14.5", - "@babel/plugin-transform-exponentiation-operator": "^7.14.5", - "@babel/plugin-transform-for-of": "^7.15.4", - "@babel/plugin-transform-function-name": "^7.14.5", - "@babel/plugin-transform-literals": "^7.14.5", - "@babel/plugin-transform-member-expression-literals": "^7.14.5", - "@babel/plugin-transform-modules-amd": "^7.14.5", - "@babel/plugin-transform-modules-commonjs": "^7.15.4", - "@babel/plugin-transform-modules-systemjs": "^7.15.4", - "@babel/plugin-transform-modules-umd": "^7.14.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.9", - "@babel/plugin-transform-new-target": "^7.14.5", - "@babel/plugin-transform-object-super": "^7.14.5", - "@babel/plugin-transform-parameters": "^7.15.4", - "@babel/plugin-transform-property-literals": "^7.14.5", - "@babel/plugin-transform-regenerator": "^7.14.5", - "@babel/plugin-transform-reserved-words": "^7.14.5", - "@babel/plugin-transform-shorthand-properties": "^7.14.5", - "@babel/plugin-transform-spread": "^7.15.8", - "@babel/plugin-transform-sticky-regex": "^7.14.5", - "@babel/plugin-transform-template-literals": "^7.14.5", - "@babel/plugin-transform-typeof-symbol": "^7.14.5", - "@babel/plugin-transform-unicode-escapes": "^7.14.5", - "@babel/plugin-transform-unicode-regex": "^7.14.5", - "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.15.6", - "babel-plugin-polyfill-corejs2": "^0.2.2", - "babel-plugin-polyfill-corejs3": "^0.2.5", - "babel-plugin-polyfill-regenerator": "^0.2.2", - "core-js-compat": "^3.16.0", + "@babel/plugin-transform-arrow-functions": "^7.16.7", + "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-block-scoped-functions": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.16.7", + "@babel/plugin-transform-classes": "^7.16.7", + "@babel/plugin-transform-computed-properties": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.17.7", + "@babel/plugin-transform-dotall-regex": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-exponentiation-operator": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-function-name": "^7.16.7", + "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-member-expression-literals": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.17.9", + "@babel/plugin-transform-modules-systemjs": "^7.17.8", + "@babel/plugin-transform-modules-umd": "^7.16.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.17.10", + "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-object-super": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-property-literals": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.17.9", + "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-shorthand-properties": "^7.16.7", + "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-sticky-regex": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.16.7", + "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-unicode-escapes": "^7.16.7", + "@babel/plugin-transform-unicode-regex": "^7.16.7", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.17.10", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.22.1", "semver": "^6.3.0" } }, "@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1033,57 +12706,50 @@ } }, "@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", + "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - } } }, "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.10.tgz", + "integrity": "sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.10", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.17.9", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.10", + "@babel/types": "^7.17.10", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.10.tgz", + "integrity": "sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } }, @@ -1093,16 +12759,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, "@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", @@ -1119,19 +12775,19 @@ } }, "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", + "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", "dev": true, "requires": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", + "debug": "^4.3.2", + "espree": "^9.3.2", "globals": "^13.9.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "dependencies": { @@ -1147,52 +12803,80 @@ "uri-js": "^4.2.2" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true } } }, "@grpc/grpc-js": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.7.tgz", - "integrity": "sha512-CKQVuwuSPh40tgOkR7c0ZisxYRiN05PcKPW72mQL5y++qd7CwBRoaJZvU5xfXnCJDFBmS3qZGQ71Frx6Ofo2XA==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz", + "integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==", "requires": { + "@grpc/proto-loader": "^0.6.4", "@types/node": ">=12.12.47" } }, + "@grpc/proto-loader": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.12.tgz", + "integrity": "sha512-filTVbETFnxb9CyRX98zN18ilChTuf/C5scZ2xyaOTp0EHGq0/ufX8rjqXUcSb1Gpv7eZq4M2jDvbh9BogKnrg==", + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.10.0", + "yargs": "^16.2.0" + } + }, "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.0", + "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", "minimatch": "^3.0.4" } }, "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -1215,19 +12899,28 @@ "dev": true }, "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", "slash": "^3.0.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1238,6 +12931,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1256,41 +12964,50 @@ } }, "@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", + "emittery": "^0.8.1", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1301,6 +13018,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1319,75 +13051,84 @@ } }, "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^26.6.2" + "jest-mock": "^27.5.1" } }, "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" } }, "@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", "dev": true, "requires": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" } }, "@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.2", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" + "v8-to-istanbul": "^8.1.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1398,28 +13139,25 @@ "supports-color": "^7.1.0" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "color-name": "~1.1.4" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { @@ -1434,72 +13172,72 @@ } }, "@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", "dev": true, "requires": { "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", "dev": true, "requires": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" } }, "@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1510,18 +13248,27 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1534,18 +13281,27 @@ } }, "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^15.0.0", + "@types/yargs": "^16.0.0", "chalk": "^4.0.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1556,6 +13312,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1573,75 +13344,114 @@ } } }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", + "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", + "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", + "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", + "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@matrixai/async-init": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@matrixai/async-init/-/async-init-1.6.0.tgz", - "integrity": "sha512-I24u6McZnSH2yX1l5e2H3O/Lu8IVb2fM/sVbDeRYrzejV2XLv/9g/goz2fglSrXgJ877BBFJNW2GMxVzvvyA5A==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@matrixai/async-init/-/async-init-1.7.3.tgz", + "integrity": "sha512-Sf3q5ODhVJqrYiAdGXmwj606956lgEMKGM9LMFU5scIOh13WokHo3GthjB1yh/umCV75NYvHJn60R9gnudVZ3Q==", "requires": { - "async-mutex": "^0.3.2", - "ts-custom-error": "^3.2.0" - }, - "dependencies": { - "async-mutex": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", - "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", - "requires": { - "tslib": "^2.3.1" - } - } + "@matrixai/async-locks": "^2.2.4", + "@matrixai/errors": "^1.1.1" + } + }, + "@matrixai/async-locks": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.2.4.tgz", + "integrity": "sha512-AEGQMM7zw8Mkcc0hbNpOCNKa6DW+04rVIwyZgUnPWawPqwUt5HSGaQwdXI3dXO+35G/vjJppggv+JJZsGfEjvA==", + "requires": { + "@matrixai/errors": "^1.1.1", + "@matrixai/resources": "^1.1.3", + "async-mutex": "^0.3.2" } }, "@matrixai/db": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-1.1.5.tgz", - "integrity": "sha512-zPpP/J1A3TLRaQKaGa5smualzjW4Rin4K48cpU5/9ThyXfpVBBp/mrkbDfjL/O5z6YTcuGVf2+yLck8tF8kVUw==", - "requires": { - "@matrixai/async-init": "^1.6.0", - "@matrixai/logger": "^2.0.1", - "@matrixai/workers": "^1.2.3", - "abstract-leveldown": "^7.0.0", - "async-mutex": "^0.3.1", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.3.3.tgz", + "integrity": "sha512-7yu3Cl/euV4CKs/2InuynbTtStAGankL1hkGZq3+oiO7Z3RN69sQ/pA2EOWD/W4+xeG+q1iTDP8H5e4oy2DXMA==", + "requires": { + "@matrixai/async-init": "^1.7.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/logger": "^2.1.1", + "@matrixai/resources": "^1.1.3", + "@matrixai/workers": "^1.3.3", + "@types/abstract-leveldown": "^7.2.0", "level": "7.0.1", - "levelup": "^5.0.1", - "sublevel-prefixer": "^1.0.0", - "subleveldown": "^5.0.1", - "threads": "^1.6.5", + "threads": "^1.6.5" + } + }, + "@matrixai/errors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.1.1.tgz", + "integrity": "sha512-ywhDblmPCfJCt3JTD8PB6rzREZ/Ex4UoLEGLw3fALhGV2AsU7NMax801PtsqbZcOfNEs2uOa1wqyhqyn3L8s9g==", + "requires": { "ts-custom-error": "^3.2.0" - }, - "dependencies": { - "async-mutex": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", - "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", - "requires": { - "tslib": "^2.3.1" - } - } } }, "@matrixai/id": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@matrixai/id/-/id-3.3.2.tgz", - "integrity": "sha512-gpW56P7jZILPc0oxyNQvZBkEBn30JPGpslOHIcDoKnCZR8VGZXEKX485xy1WE4MBiQHXdGeiYF8A2CluqTnu3w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@matrixai/id/-/id-3.3.3.tgz", + "integrity": "sha512-eXkxv68sCT17f6XQU8zMwgLLqwbdFm+8DoL3gXfBqfiDYxOCCQBS4L9kjUby8gRdlP7mIpkJ6oVAWCUnykGInA==", "requires": { "multiformats": "^9.4.8", "uuid": "^8.3.2" } }, "@matrixai/logger": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@matrixai/logger/-/logger-2.1.0.tgz", - "integrity": "sha512-UmLuXi2PJ03v0Scfl57217RPnjEZDRLlpfdIjIwCfju+kofnhhCI9P7OZu3/FgW147vbvSzWCrrtpwJiLROUUA==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@matrixai/logger/-/logger-2.1.1.tgz", + "integrity": "sha512-79KM0PyJTpfkALf9DK2xGniU+9gngsb5O8hcdUviWz+zR2W0hnTQq/g7tJW0YnIEhmDe/GkJf0Bnbs+gWfj3BA==" + }, + "@matrixai/resources": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@matrixai/resources/-/resources-1.1.3.tgz", + "integrity": "sha512-9zbA0NtgCtA+2hILpojshH6Pd679bIPtB8DcsPLVDzvGZP1TDwvtvZWCC3SG7oJUTzxqBI2Bfe+hypqwpvYPCw==" }, "@matrixai/workers": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.2.5.tgz", - "integrity": "sha512-ikI4K6RGKQbG68it7TXJJ5wX2csW+WpokUehTnz5r66d7o6FC3PkojE46LPLCDSwk3NVCGoQ743OZS2nuA8SRA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.3.3.tgz", + "integrity": "sha512-ID1sSJDXjM0hdWC10euWGcFofuys7+IDP+XTBh8Gq6jirn18xJs71wSy357qxLVSa7mL00qRJJfW6rljcFUK4A==", "requires": { - "@matrixai/logger": "^2.1.0", - "threads": "^1.6.5", - "ts-custom-error": "^3.2.0" + "@matrixai/async-init": "^1.7.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/logger": "^2.1.1", + "threads": "^1.6.5" } }, "@nodelib/fs.scandir": { @@ -1670,6 +13480,60 @@ "fastq": "^1.6.0" } }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -1680,9 +13544,9 @@ } }, "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" @@ -1718,10 +13582,15 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "@types/abstract-leveldown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", + "integrity": "sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ==" + }, "@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1732,9 +13601,9 @@ } }, "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -1751,9 +13620,9 @@ } }, "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "version": "7.17.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", + "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -1769,9 +13638,9 @@ } }, "@types/google-protobuf": { - "version": "3.15.5", - "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.5.tgz", - "integrity": "sha512-6bgv24B+A2bo9AfzReeg5StdiijKzwwnRflA8RLd1V4Yv995LeTmo0z69/MPbBDFSiZWdZHQygLo/ccXhMEDgw==", + "version": "3.15.6", + "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.6.tgz", + "integrity": "sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==", "dev": true }, "@types/graceful-fs": { @@ -1784,9 +13653,9 @@ } }, "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, "@types/istanbul-lib-report": { @@ -1808,19 +13677,19 @@ } }, "@types/jest": { - "version": "26.0.24", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz", - "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-fUy7YRpT+rHXto1YlL+J9rs0uLGyiqVt3ZOTQR+4ROc47yNl8WLdVLgUloBRhOxP1PZvguHl44T3H0wAWxahYQ==", "dev": true, "requires": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" } }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/json5": { @@ -1829,6 +13698,11 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "@types/nexpect": { "version": "0.4.31", "resolved": "https://registry.npmjs.org/@types/nexpect/-/nexpect-0.4.31.tgz", @@ -1839,9 +13713,9 @@ } }, "@types/node": { - "version": "14.17.27", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.27.tgz", - "integrity": "sha512-94+Ahf9IcaDuJTle/2b+wzvjmutxXAEXU6O81JHblYXUg2BDG+dnBy7VxIPHKAyEEDHzCMQydTJuWvrE+Aanzw==" + "version": "16.11.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.35.tgz", + "integrity": "sha512-QXu45LyepgnhUfnIAj/FyT4uM87ug5KpIrgXfQtUPNAlx8w5hmd8z8emqCLNvG11QkpRSCG9Qg2buMxvqfjfsQ==" }, "@types/node-forge": { "version": "0.9.10", @@ -1852,22 +13726,16 @@ "@types/node": "*" } }, - "@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, "@types/pako": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.2.tgz", - "integrity": "sha512-8UJl2MjkqqS6ncpLZqRZ5LmGiFBkbYxocD4e4jmBqGvfRG1RS23gKsBQbdtV9O9GvRyjFTiRHRByjSlKCLlmZw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.4.tgz", + "integrity": "sha512-Z+5bJSm28EXBSUJEgx29ioWeEEHUh6TiMkZHDhLwjc9wVFH+ressbkmX6waUZc5R3Gobn4Qu5llGxaoflZ+yhA==", "dev": true }, "@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.1.tgz", + "integrity": "sha512-XFjFHmaLVifrAKaZ+EKghFHtHSUonyw8P2Qmy2/+osBnrKbH9UYtlK10zg8/kCt47MFilll/DEDKy3DHfJ0URw==", "dev": true }, "@types/prompts": { @@ -1880,9 +13748,9 @@ } }, "@types/readable-stream": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.11.tgz", - "integrity": "sha512-0z+/apYJwKFz/RHp6mOMxz/y7xOvWPYPevuCEyAY3gXsjtaac02E26RvxA+I96rfvmVH/dEMGXNvyJfViR1FSQ==", + "version": "2.3.13", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.13.tgz", + "integrity": "sha512-4JSCx8EUzaW9Idevt+9lsRAt1lcSccoQfE+AouM1gk8sFxnnytKNIO3wTl9Dy+4m6jRJ1yXhboLHHT/LXBQiEw==", "dev": true, "requires": { "@types/node": "*", @@ -1896,34 +13764,35 @@ "dev": true }, "@types/uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", - "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.23.0.tgz", + "integrity": "sha512-hEcSmG4XodSLiAp1uxv/OQSGsDY6QN3TcRU32gANp+19wGE1QQZLRS8/GV58VRUoXhnkuJ3ZxNQ3T6Z6zM59DA==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/type-utils": "5.23.0", + "@typescript-eslint/utils": "5.23.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -1933,9 +13802,9 @@ }, "dependencies": { "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -1943,56 +13812,53 @@ } } }, - "@typescript-eslint/experimental-utils": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz", - "integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==", + "@typescript-eslint/parser": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.23.0.tgz", + "integrity": "sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw==", "dev": true, "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", + "debug": "^4.3.2" } }, - "@typescript-eslint/parser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", - "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", + "@typescript-eslint/scope-manager": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.23.0.tgz", + "integrity": "sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "debug": "^4.3.2" + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0" } }, - "@typescript-eslint/scope-manager": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", - "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "@typescript-eslint/type-utils": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.23.0.tgz", + "integrity": "sha512-iuI05JsJl/SUnOTXA9f4oI+/4qS/Zcgk+s2ir+lRmXI+80D8GaGwoUqs4p+X+4AxDolPpEpVUdlEH4ADxFy4gw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" + "@typescript-eslint/utils": "5.23.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", - "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.23.0.tgz", + "integrity": "sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", - "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.23.0.tgz", + "integrity": "sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -2001,9 +13867,9 @@ }, "dependencies": { "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -2011,28 +13877,34 @@ } } }, + "@typescript-eslint/utils": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.23.0.tgz", + "integrity": "sha512-dbgaKN21drqpkbbedGMNPCtRPZo1IOUr5EI9Jrrh99r5UW5Q0dz46RKXeSBoPV+56R6dFKpbrdhgUNSJsDDRZA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, "@typescript-eslint/visitor-keys": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", - "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.23.0.tgz", + "integrity": "sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/types": "5.23.0", "eslint-visitor-keys": "^3.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", - "dev": true - } } }, "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, "abstract-leveldown": { @@ -2049,9 +13921,9 @@ } }, "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", "dev": true }, "acorn-globals": { @@ -2062,13 +13934,22 @@ "requires": { "acorn": "^7.1.1", "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } } }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -2096,12 +13977,6 @@ "uri-js": "^4.2.2" } }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -2109,29 +13984,20 @@ "dev": true, "requires": { "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } } }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" } }, "anymatch": { @@ -2207,33 +14073,15 @@ "sprintf-js": "~1.0.2" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "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==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", "get-intrinsic": "^1.1.1", "is-string": "^1.0.7" } @@ -2244,39 +14092,22 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" } }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, "async-lock": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.0.tgz", - "integrity": "sha512-8A7SkiisnEgME2zEedtDYPxUPzdv3x//E7n5IFktPAtMYSEAV7eNJF0rMwrVyUFj6d/8rgajLantbjcNRQYXIg==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.1.tgz", + "integrity": "sha512-zK7xap9UnttfbE23JmcrNIyueAn6jWshihJqA33U/hEnKprF/lVGBDsBv/bqLm2YMMl1DnpHhUY044eA0t1TUw==" }, "async-mutex": { "version": "0.3.2", @@ -2298,28 +14129,31 @@ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, "babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "dev": true, "requires": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2330,6 +14164,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2370,9 +14219,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -2382,33 +14231,33 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", - "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", + "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", "dev": true, "requires": { "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.2", + "@babel/helper-define-polyfill-provider": "^0.3.1", "semver": "^6.1.1" } }, "babel-plugin-polyfill-corejs3": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz", - "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", + "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.2", - "core-js-compat": "^3.16.2" + "@babel/helper-define-polyfill-provider": "^0.3.1", + "core-js-compat": "^3.21.0" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", - "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", + "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.2.2" + "@babel/helper-define-polyfill-provider": "^0.3.1" } }, "babel-preset-current-node-syntax": { @@ -2432,12 +14281,12 @@ } }, "babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.6.2", + "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -2448,6 +14297,13 @@ "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } } }, "balanced-match": { @@ -2456,71 +14312,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, - "big-integer": { - "version": "1.6.50", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.50.tgz", - "integrity": "sha512-+O2uoQWFRo8ysZNo/rjtri2jIwjr3XfeAgRjAUADRqGG+ZITvyn8J1kvXLTaKVr3hhGXk+f23tKfdzmklVM9vQ==" - }, "bip39": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", @@ -2598,15 +14394,15 @@ "dev": true }, "browserslist": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", "escalade": "^3.1.1", - "node-releases": "^2.0.0", + "node-releases": "^2.0.3", "picocolors": "^1.0.0" } }, @@ -2643,23 +14439,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "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" - } - }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -2681,32 +14460,20 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001269", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", - "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", + "version": "1.0.30001340", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001340.tgz", + "integrity": "sha512-jUNz+a9blQTQVu4uFcn17uAD8IDizPzQkIKh3LCJfg9BkyIqExYYdyc/ZSlWUSKb8iYiXxKsxbv4zYSvkqjrxw==", "dev": true }, "canonicalize": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.5.tgz", - "integrity": "sha512-mAjKJPIyP0xqqv6IAkvso07StOmz6cmGtNDg3pXCSzXVZOqka7StIkAhJl/zHOi4M2CgpYfD6aeRWbnrmtvBEA==" - }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "requires": { - "rsvp": "^4.8.4" - } + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.8.tgz", + "integrity": "sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==" }, "catering": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.0.tgz", - "integrity": "sha512-M5imwzQn6y+ODBfgi+cfgZv2hIUI6oYU/0f35Mdb1ujGeqeoI5tOnl9Q13DTH7LW+7er+NYq8stNOKZD/Z3U/A==", - "requires": { - "queue-tick": "^1.0.0" - } + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==" }, "chalk": { "version": "2.4.2", @@ -2717,32 +14484,6 @@ "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - } } }, "char-regex": { @@ -2772,15 +14513,15 @@ } }, "cheerio-select": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", - "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", + "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", "requires": { - "css-select": "^4.1.3", - "css-what": "^5.0.1", + "css-select": "^4.3.0", + "css-what": "^6.0.1", "domelementtype": "^2.2.0", - "domhandler": "^4.2.0", - "domutils": "^2.7.0" + "domhandler": "^4.3.1", + "domutils": "^2.8.0" } }, "chownr": { @@ -2790,9 +14531,9 @@ "dev": true }, "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", "dev": true }, "cipher-base": { @@ -2805,34 +14546,11 @@ } }, "cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, - "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==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, "clean-git-ref": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", @@ -2842,11 +14560,27 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } } }, "co": { @@ -2867,29 +14601,19 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "color-name": "~1.1.4" + "color-name": "1.1.3" } }, "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "combined-stream": { @@ -2906,12 +14630,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2941,24 +14659,18 @@ } } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, "core-js": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, "core-js-compat": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.18.3.tgz", - "integrity": "sha512-4zP6/y0a2RTHN5bRGT7PTq9lVt3WzvffTNjqnTKsXhkAYNDTkdCLOIfAdOLcQ/7TDdyRj3c+NeHe1NmF1eDScw==", + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.5.tgz", + "integrity": "sha512-rEF75n3QtInrYICvJjrAgV03HwKiYvtKHdPtaba1KucG+cNZ4NJnH9isqt979e67KZlhpbCOTwnsvnIr+CVeOg==", "dev": true, "requires": { - "browserslist": "^4.17.3", + "browserslist": "^4.20.3", "semver": "7.0.0" }, "dependencies": { @@ -2977,13 +14689,9 @@ "dev": true }, "crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - } + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" }, "create-hash": { "version": "1.2.0", @@ -3017,11 +14725,11 @@ "dev": true }, "cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "requires": { - "node-fetch": "2.6.1" + "node-fetch": "2.6.7" } }, "cross-spawn": { @@ -3035,21 +14743,21 @@ } }, "css-select": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", - "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "requires": { "boolbase": "^1.0.0", - "css-what": "^5.0.0", - "domhandler": "^4.2.0", - "domutils": "^2.6.0", - "nth-check": "^2.0.0" + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" } }, "css-what": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", - "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" }, "cssom": { "version": "0.4.4", @@ -3086,39 +14794,33 @@ } }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, "decimal.js": { "version": "10.3.1", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "requires": { - "mimic-response": "^2.0.0" + "mimic-response": "^3.1.0" } }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -3147,59 +14849,14 @@ } }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, - "defined": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz", - "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=" - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3231,9 +14888,9 @@ "dev": true }, "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "dev": true }, "diff3": { @@ -3260,9 +14917,9 @@ } }, "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -3270,9 +14927,9 @@ } }, "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" }, "domexception": { "version": "2.0.1", @@ -3292,9 +14949,9 @@ } }, "domhandler": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "requires": { "domelementtype": "^2.2.0" } @@ -3310,22 +14967,21 @@ } }, "electron-to-chromium": { - "version": "1.3.871", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", - "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", "dev": true }, "emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "dev": true }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "encoding-down": { "version": "7.1.0", @@ -3339,23 +14995,31 @@ } }, "encryptedfs": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.4.3.tgz", - "integrity": "sha512-OQqsGw3eNrMdFpiYRX17nMq1NKKebaA0KXyM9IRY9aPOxpaeOwcdvWnOcvvO9wCxZFNxgy/A2SOZdxnhCe3paA==", - "requires": { - "@matrixai/async-init": "^1.6.0", - "@matrixai/db": "^1.1.5", - "@matrixai/logger": "^2.1.0", - "@matrixai/workers": "^1.2.5", - "async-mutex": "^0.3.2", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.1.tgz", + "integrity": "sha512-gGyL8Ax61WAte3ABiz26WuFSIhEmTh0KcGfugkQunpdcEKoex/3T+2l6InCv35VSFAQ/l5vbBFAYFdKT15JL2w==", + "requires": { + "@matrixai/async-init": "^1.7.3", + "@matrixai/async-locks": "^2.2.4", + "@matrixai/db": "3.3.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/logger": "^2.1.1", + "@matrixai/resources": "^1.1.3", + "@matrixai/workers": "^1.3.3", "errno": "^0.1.7", "lexicographic-integer": "^1.1.0", - "node-forge": "^0.10.0", + "node-forge": "^1.3.1", "readable-stream": "^3.6.0", "resource-counter": "^1.2.4", "threads": "^1.6.5", - "ts-custom-error": "^3.2.0", "util-callbackify": "^1.0.0" + }, + "dependencies": { + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" + } } }, "end-of-stream": { @@ -3367,15 +15031,6 @@ "once": "^1.4.0" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -3399,30 +15054,42 @@ } }, "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.0.tgz", + "integrity": "sha512-URbD8tgRthKD3YcC39vbvSDrX23upXnPcnGAjQfgxXF5ID75YcENawc9ZX/9iTP9ptUyfCLIxTTuMYoRfiOVKA==", "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.1", "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.2", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", + "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "regexp.prototype.flags": "^1.4.1", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" } }, "es-to-primitive": { @@ -3438,8 +15105,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-string-regexp": { "version": "1.0.5", @@ -3461,9 +15127,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "levn": { @@ -3496,13 +15162,6 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -3515,62 +15174,48 @@ } }, "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", + "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", "dev": true, "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", + "@eslint/eslintrc": "^1.2.3", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", + "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -3583,6 +15228,21 @@ "uri-js": "^4.2.2" } }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3593,33 +15253,47 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -3631,11 +15305,14 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } }, "json-schema-traverse": { "version": "0.4.1", @@ -3643,15 +15320,6 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3660,14 +15328,21 @@ "requires": { "has-flag": "^4.0.0" } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true } } }, "eslint-config-prettier": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", - "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", - "dev": true + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "requires": {} }, "eslint-import-resolver-node": { "version": "0.3.6", @@ -3691,14 +15366,13 @@ } }, "eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", "dev": true, "requires": { "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" + "find-up": "^2.1.0" }, "dependencies": { "debug": { @@ -3758,22 +15432,13 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } } } }, "eslint-plugin-import": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", - "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -3781,14 +15446,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.1", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "dependencies": { "debug": { @@ -3818,9 +15483,9 @@ } }, "eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" @@ -3843,12 +15508,20 @@ "dev": true, "requires": { "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "esm": { @@ -3858,22 +15531,14 @@ "optional": true }, "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" } }, "esprima": { @@ -3892,9 +15557,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -3909,9 +15574,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -3928,243 +15593,45 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true - }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "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==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true + }, + "expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" } }, "fast-deep-equal": { @@ -4179,17 +15646,17 @@ "dev": true }, "fast-fuzzy": { - "version": "1.10.10", - "resolved": "https://registry.npmjs.org/fast-fuzzy/-/fast-fuzzy-1.10.10.tgz", - "integrity": "sha512-TkXYYQcLyZ5tbDpg3kj5gq7PNl6vQQQEW99/sBpmYYRPcuCaZElm3FpoOOqwL51+1prhjrzsnGAjWgNCG7iVOA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fast-fuzzy/-/fast-fuzzy-1.11.1.tgz", + "integrity": "sha512-FaO8kAsdAqV0SOBbLelpuBNar4C6lUS82OqDlM6Y/I0Q9joMmxAxll8AMrfTLp82rRuZj/2+BzFZgOHA18vN6A==", "requires": { "graphemesplit": "^2.4.1" } }, "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -4197,6 +15664,17 @@ "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, "fast-json-stable-stringify": { @@ -4236,13 +15714,6 @@ "requires": { "napi-macros": "^2.0.0", "node-gyp-build": "^4.2.2" - }, - "dependencies": { - "node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" - } } }, "file-entry-cache": { @@ -4284,15 +15755,9 @@ } }, "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, "form-data": { @@ -4306,15 +15771,6 @@ "mime-types": "^2.1.12" } }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -4373,14 +15829,6 @@ "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } } }, "fs.realpath": { @@ -4401,12 +15849,28 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "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==" + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -4429,26 +15893,6 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -4469,8 +15913,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { "version": "1.1.1", @@ -4489,13 +15932,10 @@ "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true }, "get-symbol-description": { "version": "1.0.0", @@ -4506,12 +15946,6 @@ "get-intrinsic": "^1.1.1" } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -4533,12 +15967,12 @@ } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" } }, "globals": { @@ -4548,28 +15982,28 @@ "dev": true }, "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" } }, "google-protobuf": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.18.1.tgz", - "integrity": "sha512-cDqSamZ8rGs+pOzhIsBte7wpezUKg/sggeptDWN5odhnRY/eDLa5VWLeNeQvcfiqjS3yUwgM+6OePCJMB7aWZA==" + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.20.1.tgz", + "integrity": "sha512-XMf1+O32FjYIV3CYu6Tuh5PNbfNEU5Xu22X+Xkdb/DUexFlCzhvv7d5Iirm4AOwn8lv4al1YvIhzGrg2j9Zfzw==" }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, "graphemesplit": { @@ -4581,13 +16015,6 @@ "unicode-trie": "^2.0.0" } }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true, - "optional": true - }, "grpc_tools_node_protoc_ts": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/grpc_tools_node_protoc_ts/-/grpc_tools_node_protoc_ts-5.3.2.tgz", @@ -4617,14 +16044,6 @@ "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "has": { @@ -4636,9 +16055,9 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" }, "has-flag": { "version": "3.0.0", @@ -4646,10 +16065,18 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { "version": "1.0.0", @@ -4665,64 +16092,6 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -4733,12 +16102,6 @@ "safe-buffer": "^5.2.0" } }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -4777,9 +16140,9 @@ } }, "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "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==", "dev": true, "requires": { "agent-base": "6", @@ -4787,9 +16150,9 @@ } }, "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, "iconv-lite": { @@ -4807,14 +16170,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" }, "import-fresh": { "version": "3.3.0", @@ -4835,9 +16193,9 @@ } }, "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "requires": { "pkg-dir": "^4.2.0", @@ -4892,38 +16250,9 @@ } }, "ip-num": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/ip-num/-/ip-num-1.3.3.tgz", - "integrity": "sha512-1QsiMKglDaemuIktincG1ntr3DvVTV/pU++eyG7vIm4xd+gvtJ9eoB34RRbI9YTqn1U5og16n7+1RgwLhv4RmA==", - "requires": { - "big-integer": "^1.6.48" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ip-num/-/ip-num-1.4.0.tgz", + "integrity": "sha512-MP+gq4uBvrvm+G7EwP14GcJeFK49/p6sZrNOarMUoExLRodULJQM8mnkb/SbT1YKxRsZfh8rgwei2pUJIa35jA==" }, "is-arrayish": { "version": "0.2.1", @@ -4958,50 +16287,15 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "dev": true, "requires": { "has": "^1.0.3" } }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -5010,38 +16304,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "optional": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5049,10 +16311,13 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } }, "is-generator-fn": { "version": "2.1.0", @@ -5070,9 +16335,9 @@ } }, "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" }, "is-number": { "version": "7.0.0", @@ -5081,9 +16346,9 @@ "dev": true }, "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "requires": { "has-tostringtag": "^1.0.0" } @@ -5093,15 +16358,6 @@ "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", "integrity": "sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==" }, - "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==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -5118,14 +16374,17 @@ } }, "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } }, "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-string": { @@ -5151,27 +16410,11 @@ "dev": true }, "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "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==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "optional": true, + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "requires": { - "is-docker": "^2.0.0" + "call-bind": "^1.0.2" } }, "isarray": { @@ -5185,16 +16428,10 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, "isomorphic-git": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.10.1.tgz", - "integrity": "sha512-abbPpKkykIVDJ92rtYoD4AOuT5/7PABHR2fDBrsm7H0r2ZT+MGpPL/FynrEJM6nTcFSieaIDxnHNGhfHO/v+bA==", + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.17.2.tgz", + "integrity": "sha512-KtYyJye7Ad1XSgObsw7dwn3OaEcGUy04BHv6D+qBz2BWY7T7q7HXBzoSOiVvVMbOo+K2EZ2MUT+g2QkpJCPQLQ==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -5206,25 +16443,25 @@ "pify": "^4.0.1", "readable-stream": "^3.4.0", "sha.js": "^2.4.9", - "simple-get": "^3.0.2" + "simple-get": "^4.0.1" } }, "istanbul-lib-coverage": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.1.0.tgz", - "integrity": "sha512-OFSPP1Csv3GxruycNA1iRJPnc5pon+N4Q89EUz8KYOFbdsqCoHRh0J8jwRdna5thveVcMTdgY27kUl/lZuAWdw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, "istanbul-lib-instrument": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.0.4.tgz", - "integrity": "sha512-W6jJF9rLGEISGoCyXRqa/JCGQGmmxPO10TMu7izaUTynxvBvTjqzAIIGCK9USBmIbQAaSWD6XJPrM9Pv5INknw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", + "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", "dev": true, "requires": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" } }, @@ -5265,20 +16502,12 @@ "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -5286,16 +16515,63 @@ } }, "jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "dev": true, "requires": { - "@jest/core": "^26.6.3", + "@jest/core": "^27.5.1", "import-local": "^3.0.2", - "jest-cli": "^26.6.3" + "jest-cli": "^27.5.1" + } + }, + "jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5306,44 +16582,27 @@ "supports-color": "^7.1.0" } }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dev": true, - "requires": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5352,135 +16611,121 @@ "requires": { "has-flag": "^4.0.0" } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, - "jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" }, "dependencies": { - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" + "color-convert": "^2.0.1" } }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "pump": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "is-stream": { + "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "path-key": "^3.0.0" + "has-flag": "^4.0.0" } } } }, "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5491,6 +16736,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5509,17 +16769,26 @@ } }, "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5530,6 +16799,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5548,27 +16832,36 @@ } }, "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5579,6 +16872,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5597,88 +16905,95 @@ } }, "jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", "dev": true, "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" } }, "jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", "dev": true, "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" } }, "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true }, "jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", "dev": true, "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.6.2", + "expect": "^27.5.1", "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5689,6 +17004,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5707,27 +17037,36 @@ } }, "jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", "dev": true, "requires": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5738,6 +17077,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5756,22 +17110,31 @@ } }, "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^2.0.3" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5782,6 +17145,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5800,12 +17178,12 @@ } }, "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/node": "*" } }, @@ -5813,42 +17191,56 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jest-mock-process/-/jest-mock-process-1.4.1.tgz", "integrity": "sha512-ZZUKRlEBizutngoO4KngzN30YoeAYP3nnwimk4cpi9WqLxQUf6SlAPK5p1D9usEpxDS3Uif2MIez3Bq0vGYR+g==", - "dev": true + "dev": true, + "requires": {} }, "jest-mock-props": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/jest-mock-props/-/jest-mock-props-1.9.0.tgz", - "integrity": "sha512-8IlIiZRvovnRuvqcvWZyDv4CyhrUGTbEW/1eKurHr2JY4VhIWQIPlbpt9lqL2nxdGnco+OcgpPBwGYCEeDb2+A==", - "dev": true + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/jest-mock-props/-/jest-mock-props-1.9.1.tgz", + "integrity": "sha512-PvTySOTw/K4dwL7XrVGq/VUZRm/qXPrV4+NuhgxuWkmE3h/Fd+g+qB0evK5vSBAkI8TaxvTXYv17IdxWdEze1g==", + "dev": true, + "requires": {} }, "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "dev": true }, "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", "slash": "^3.0.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5859,6 +17251,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5877,44 +17284,54 @@ } }, "jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" } }, "jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "throat": "^6.0.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5925,6 +17342,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5943,40 +17375,44 @@ } }, "jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", + "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", + "execa": "^5.0.0", "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" + "strip-bom": "^4.0.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5987,17 +17423,21 @@ "supports-color": "^7.1.0" } }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6012,89 +17452,58 @@ "requires": { "has-flag": "^4.0.0" } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, "jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dev": true, "requires": { "@types/node": "*", - "graceful-fs": "^4.2.4" + "graceful-fs": "^4.2.9" } }, "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", "dev": true, "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", + "pretty-format": "^27.5.1", "semver": "^7.3.2" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -6105,6 +17514,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6112,9 +17536,9 @@ "dev": true }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -6132,19 +17556,28 @@ } }, "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -6155,6 +17588,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6173,23 +17621,32 @@ } }, "jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", + "jest-get-type": "^27.5.1", "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "pretty-format": "^27.5.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "chalk": { @@ -6202,6 +17659,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6220,20 +17692,29 @@ } }, "jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", "dev": true, "requires": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.6.2", + "jest-util": "^27.5.1", "string-length": "^4.0.1" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -6244,6 +17725,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6262,14 +17758,14 @@ } }, "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" }, "dependencies": { "has-flag": { @@ -6279,9 +17775,9 @@ "dev": true }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -6290,9 +17786,9 @@ } }, "jose": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.3.6.tgz", - "integrity": "sha512-A/JgZGUerqG2IMuxkUDBtZ4aTxg/l1Y+pt/QAAYiRAR3EFlxIE0Su0xdpB8tQcPZK5eudB7g1PHCZ5uHatbY+g==" + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.8.1.tgz", + "integrity": "sha512-+/hpTbRcCw9YC0TOfN1W47pej4a9lRmltdOVdRLz5FP5UvUq3CenhXjQK7u/8NdMIIShMXYAh9VLPhc7TjhvFw==" }, "js-base64": { "version": "3.7.2", @@ -6348,14 +17844,6 @@ "whatwg-url": "^8.5.0", "ws": "^7.4.6", "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - } } }, "jsesc": { @@ -6382,13 +17870,10 @@ "dev": true }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true }, "jsonc-parser": { "version": "3.0.0", @@ -6404,22 +17889,8 @@ "requires": { "graceful-fs": "^4.1.6", "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } } }, - "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==", - "dev": true - }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -6483,14 +17954,6 @@ "run-parallel-limit": "^1.1.0" } }, - "level-option-wrap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/level-option-wrap/-/level-option-wrap-1.1.0.tgz", - "integrity": "sha1-rSDmjZ88IsiJdTHMaqevWWse0Sk=", - "requires": { - "defined": "~0.0.0" - } - }, "level-packager": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-6.0.1.tgz", @@ -6506,20 +17969,13 @@ "integrity": "sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA==" }, "leveldown": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-6.1.0.tgz", - "integrity": "sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-6.1.1.tgz", + "integrity": "sha512-88c+E+Eizn4CkQOBHwqlCJaTNEjGpaEIikn1S+cINc5E9HEvJ77bqY4JY/HxT5u0caWqsc3P3DcFIKBI1vHt+A==", "requires": { "abstract-leveldown": "^7.2.0", "napi-macros": "~2.0.0", "node-gyp-build": "^4.3.0" - }, - "dependencies": { - "node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" - } } }, "levelup": { @@ -6557,9 +18013,9 @@ "integrity": "sha1-UsptmYpXLmMitRX1uA45bGBD6bg=" }, "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, "locate-path": { @@ -6577,11 +18033,10 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, "lodash.debounce": { "version": "4.0.8", @@ -6589,17 +18044,22 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, "lru-cache": { "version": "6.0.0", @@ -6637,33 +18097,18 @@ "dev": true }, "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, - "requires": { - "tmpl": "1.0.x" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "requires": { - "object-visit": "^1.0.0" + "tmpl": "1.0.5" } }, "marked": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/marked/-/marked-3.0.7.tgz", - "integrity": "sha512-ctKqbnLuNbsHbI26cfMyOlKgXGfl1orOv1AvWWDX7AkgfMOwCWvmuYc+mVLeWhQ9W6hdWVBynOs96VkcscKo0Q==", + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.15.tgz", + "integrity": "sha512-esX5lPdTfG4p8LDkv+obbRCyOKzB+820ZZyMOXJZygZBHrH9b3xXR64X4kT3sPe9Nx8qQXbmcz6kFSMt4Nfk6Q==", "dev": true }, "md5.js": { @@ -6689,28 +18134,28 @@ "dev": true }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true }, "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "requires": { - "mime-db": "1.50.0" + "mime-db": "1.52.0" } }, "mimic-fn": { @@ -6720,23 +18165,23 @@ "dev": true }, "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minimisted": { "version": "2.0.1", @@ -6746,33 +18191,6 @@ "minimist": "^1.2.5" } }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "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==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -6789,6 +18207,17 @@ "debug": "4.3.2", "lazy-ass": "1.6.0", "ramda": "0.27.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } } }, "ms": { @@ -6797,9 +18226,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "multiformats": { - "version": "9.4.9", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.4.9.tgz", - "integrity": "sha512-zA84TTJcRfRMpjvYqy63piBbSEdqlIGqNNSpP6kspqtougqjo60PRhIFo+oAxrjkof14WMCImvr7acK6rPpXLw==" + "version": "9.6.5", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.6.5.tgz", + "integrity": "sha512-vMwf/FUO+qAPvl3vlSZEgEVFY/AxeZq5yg761ScF3CZsXgmTi/HGkicUiNN0CI4PW8FiY2P0OLklOcmQjdQJhw==" }, "multistream": { "version": "4.1.0", @@ -6811,25 +18240,6 @@ "readable-stream": "^3.6.0" } }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "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" - } - }, "napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -6937,9 +18347,33 @@ } }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } }, "node-forge": { "version": "0.10.0", @@ -6947,10 +18381,9 @@ "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", - "dev": true + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==" }, "node-int64": { "version": "0.4.0", @@ -6958,71 +18391,12 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", "dev": true }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", - "dev": true, - "optional": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, "node-releases": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", - "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", - "dev": true - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", + "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", "dev": true }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7030,20 +18404,12 @@ "dev": true }, "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "path-key": "^2.0.0" - }, - "dependencies": { - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - } + "path-key": "^3.0.0" } }, "npmlog": { @@ -7084,62 +18450,16 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", @@ -7161,15 +18481,6 @@ "es-abstract": "^1.19.1" } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "object.values": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", @@ -7203,32 +18514,6 @@ "mimic-fn": "^2.1.0" } }, - "onigasm": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/onigasm/-/onigasm-2.2.5.tgz", - "integrity": "sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==", - "dev": true, - "requires": { - "lru-cache": "^5.1.1" - }, - "dependencies": { - "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==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } - } - }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -7243,18 +18528,6 @@ "word-wrap": "^1.2.3" } }, - "p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, "p-is-promise": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", @@ -7324,12 +18597,6 @@ "parse5": "^6.0.1" } }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7378,9 +18645,9 @@ "dev": true }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pify": { @@ -7389,54 +18656,59 @@ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true }, "pkg": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.3.0.tgz", - "integrity": "sha512-/DGG+QcSPraMAIxaoGCNqb2A6Xkm2jBQMsj2mjb4ag236ByTY9Xhpikvj5ixwlSQV0euuJw4fphKCd5YHRPS8w==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.6.0.tgz", + "integrity": "sha512-mHrAVSQWmHA41RnUmRpC7pK9lNnMfdA16CF3cqOI22a8LZxOQzF7M8YWtA2nfs+d7I0MTDXOtkDsAsFXeCpYjg==", "dev": true, "requires": { - "@babel/parser": "7.13.13", - "@babel/types": "7.13.12", - "chalk": "^4.1.0", + "@babel/parser": "7.16.2", + "@babel/types": "7.16.0", + "chalk": "^4.1.2", "escodegen": "^2.0.0", "fs-extra": "^9.1.0", - "globby": "^11.0.3", + "globby": "^11.0.4", "into-stream": "^6.0.0", "minimist": "^1.2.5", "multistream": "^4.1.0", - "pkg-fetch": "3.1.1", - "prebuild-install": "6.0.1", + "pkg-fetch": "3.3.0", + "prebuild-install": "6.1.4", "progress": "^2.0.3", "resolve": "^1.20.0", "stream-meter": "^1.0.4", - "tslib": "2.1.0" + "tslib": "2.3.1" }, "dependencies": { "@babel/parser": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", - "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", + "version": "7.16.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz", + "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==", "dev": true }, "@babel/types": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz", - "integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" } }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -7447,6 +18719,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7463,9 +18750,9 @@ } }, "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true } } @@ -7480,20 +18767,30 @@ } }, "pkg-fetch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.1.1.tgz", - "integrity": "sha512-3GfpNwbwoTxge2TrVp6Oyz/FZJOoxF1r0+1YikOhnBXa2Di/VOJKtUObFHap76BFnyFo1fwh5vARWFR9TzLKUg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.3.0.tgz", + "integrity": "sha512-xJnIZ1KP+8rNN+VLafwu4tEeV4m8IkFBDdCFqmAJz9K1aiXEtbARmdbEe6HlXWGSVuShSHjFXpfkKRkDBQ5kiA==", "dev": true, "requires": { - "chalk": "^4.1.0", + "chalk": "^4.1.2", "fs-extra": "^9.1.0", "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.6", "progress": "^2.0.3", "semver": "^7.3.5", + "tar-fs": "^2.1.1", "yargs": "^16.2.0" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -7504,6 +18801,21 @@ "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7511,9 +18823,9 @@ "dev": true }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -7530,16 +18842,10 @@ } } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, "prebuild-install": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.1.tgz", - "integrity": "sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", "dev": true, "requires": { "detect-libc": "^1.0.3", @@ -7548,15 +18854,41 @@ "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", + "node-abi": "^2.21.0", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^3.0.3", "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "requires": { + "mimic-response": "^2.0.0" + } + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true + }, + "simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + } } }, "prelude-ls": { @@ -7566,9 +18898,9 @@ "dev": true }, "prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", + "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", "dev": true }, "prettier-linter-helpers": { @@ -7581,22 +18913,24 @@ } }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, - "printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -7618,6 +18952,26 @@ "sisteransi": "^1.0.5" } }, + "protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -7649,11 +19003,6 @@ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, - "queue-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.0.tgz", - "integrity": "sha512-ULWhjjE8BmiICGn3G8+1L9wFpERNxkf8ysxkAer4+TFdRefDaXOCV5m92aMB9FtBVmn/8sETXLXY6BfW7hyaWQ==" - }, "ramda": { "version": "0.27.1", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", @@ -7688,56 +19037,12 @@ } } }, - "reachdown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reachdown/-/reachdown-1.1.0.tgz", - "integrity": "sha512-6LsdRe4cZyOjw4NnvbhUd/rGG7WQ9HMopPr+kyL018Uci4kijtxcGR5kVb5Ln13k4PEE+fEFQbjfOvNw7cnXmA==" - }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -7755,36 +19060,37 @@ "dev": true }, "regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", "dev": true, "requires": { "regenerate": "^1.4.2" } }, "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true }, "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", "dev": true, "requires": { "@babel/runtime": "^7.8.4" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" } }, "regexpp": { @@ -7794,29 +19100,29 @@ "dev": true }, "regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", + "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", "dev": true, "requires": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.0.0" } }, "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", "dev": true }, "regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -7830,49 +19136,25 @@ } } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "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==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "dev": true, "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-cwd": { @@ -7890,10 +19172,10 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, "resource-counter": { @@ -7905,12 +19187,6 @@ "bitset": "^5.0.3" } }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -7935,12 +19211,6 @@ "inherits": "^2.0.1" } }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7963,168 +19233,12 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "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" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, "saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", @@ -8146,29 +19260,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "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==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -8191,21 +19282,14 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, "shiki": { - "version": "0.9.12", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.12.tgz", - "integrity": "sha512-VXcROdldv0/Qu0w2XvzU4IrvTeBNs/Kj/FCmtcEXGz7Tic/veQzliJj6tEiAgoKianhQstpYmbPDStHU5Opqcw==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", "dev": true, "requires": { "jsonc-parser": "^3.0.0", - "onigasm": "^2.2.5", + "vscode-oniguruma": "^1.6.1", "vscode-textmate": "5.2.0" } }, @@ -8220,9 +19304,9 @@ } }, "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "simple-concat": { @@ -8231,11 +19315,11 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "requires": { - "decompress-response": "^4.2.0", + "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } @@ -8251,227 +19335,20 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "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==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "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==", - "dev": true, - "requires": { - "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" - } - }, "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "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==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" } }, "sprintf-js": { @@ -8497,27 +19374,6 @@ } } }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, "stream-meter": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", @@ -8559,6 +19415,14 @@ } } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -8570,47 +19434,57 @@ } }, "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -8621,12 +19495,6 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -8639,132 +19507,6 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, - "sublevel-prefixer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sublevel-prefixer/-/sublevel-prefixer-1.0.0.tgz", - "integrity": "sha1-TuRZ72Y6yFvyj8ZJ17eWX9ppEHM=" - }, - "subleveldown": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/subleveldown/-/subleveldown-5.0.1.tgz", - "integrity": "sha512-cVqd/URpp7si1HWu5YqQ3vqQkjuolAwHypY1B4itPlS71/lsf6TQPZ2Y0ijT22EYVkvH5ove9JFJf4u7VGPuZw==", - "requires": { - "abstract-leveldown": "^6.3.0", - "encoding-down": "^6.2.0", - "inherits": "^2.0.3", - "level-option-wrap": "^1.1.0", - "levelup": "^4.4.0", - "reachdown": "^1.1.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", - "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "requires": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - } - } - }, - "encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "requires": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - } - }, - "level-codec": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", - "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", - "requires": { - "buffer": "^5.6.0" - } - }, - "level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" - }, - "level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - } - }, - "level-supports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "requires": { - "xtend": "^4.0.2" - } - }, - "levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", - "requires": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - } - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -8801,40 +19543,18 @@ } } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "table": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", - "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - } - } - }, "tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", @@ -8900,9 +19620,9 @@ } }, "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "dev": true }, "timeout-refresh": { @@ -8936,44 +19656,6 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -8992,6 +19674,14 @@ "psl": "^1.1.33", "punycode": "^2.1.1", "universalify": "^0.1.2" + }, + "dependencies": { + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + } } }, "tr46": { @@ -9009,27 +19699,25 @@ "integrity": "sha512-cBvC2QjtvJ9JfWLvstVnI45Y46Y5dMxIaG1TDMGAD/R87hpvqFL+7LhvUDhnRCfOnx/xitollFWWvUKKKhbN0A==" }, "ts-jest": { - "version": "26.5.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", - "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", + "version": "27.1.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.4.tgz", + "integrity": "sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ==", "dev": true, "requires": { "bs-logger": "0.x", - "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", + "jest-util": "^27.0.0", "json5": "2.x", - "lodash": "4.x", + "lodash.memoize": "4.x", "make-error": "1.x", - "mkdirp": "1.x", "semver": "7.x", "yargs-parser": "20.x" }, "dependencies": { "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -9038,9 +19726,9 @@ } }, "ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.7.0", @@ -9054,15 +19742,10 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", "yn": "3.1.1" }, "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, "acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", @@ -9072,14 +19755,14 @@ } }, "tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", "dev": true, "requires": { "@types/json5": "^0.0.29", "json5": "^1.0.1", - "minimist": "^1.2.0", + "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, "dependencies": { @@ -9101,9 +19784,9 @@ } }, "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "tsutils": { "version": "3.21.0", @@ -9147,9 +19830,9 @@ "dev": true }, "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, "typedarray-to-buffer": { @@ -9162,93 +19845,59 @@ } }, "typedoc": { - "version": "0.21.9", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.21.9.tgz", - "integrity": "sha512-VRo7aII4bnYaBBM1lhw4bQFmUcDQV8m8tqgjtc7oXl87jc1Slbhfw2X5MccfcR2YnEClHDWgsiQGgNB8KJXocA==", + "version": "0.22.15", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.15.tgz", + "integrity": "sha512-CMd1lrqQbFvbx6S9G6fL4HKp3GoIuhujJReWqlIvSb2T26vGai+8Os3Mde7Pn832pXYemd9BMuuYWhFpL5st0Q==", "dev": true, "requires": { - "glob": "^7.1.7", - "handlebars": "^4.7.7", + "glob": "^7.2.0", "lunr": "^2.3.9", - "marked": "^3.0.2", - "minimatch": "^3.0.0", - "progress": "^2.0.3", - "shiki": "^0.9.8", - "typedoc-default-themes": "^0.12.10" - } - }, - "typedoc-default-themes": { - "version": "0.12.10", - "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz", - "integrity": "sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA==", - "dev": true - }, - "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true - }, - "typescript-cached-transpile": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typescript-cached-transpile/-/typescript-cached-transpile-0.0.6.tgz", - "integrity": "sha512-bfPc7YUW0PrVkQHU0xN0ANRuxdPgoYYXtZEW6PNkH5a97/AOM+kPPxSTMZbpWA3BG1do22JUkfC60KoCKJ9VZQ==", - "dev": true, - "requires": { - "@types/node": "^12.12.7", - "fs-extra": "^8.1.0", - "tslib": "^1.10.0" + "marked": "^4.0.12", + "minimatch": "^5.0.1", + "shiki": "^0.10.1" }, "dependencies": { - "@types/node": { - "version": "12.20.37", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", - "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", - "dev": true - }, - "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==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "balanced-match": "^1.0.0" } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "brace-expansion": "^2.0.1" } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true } } }, + "typescript": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "dev": true + }, "uglify-js": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", - "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", + "version": "3.15.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", + "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==", "dev": true, "optional": true }, "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, @@ -9296,22 +19945,10 @@ } } }, - "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==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "unordered-set": { @@ -9319,46 +19956,6 @@ "resolved": "https://registry.npmjs.org/unordered-set/-/unordered-set-2.0.1.tgz", "integrity": "sha512-eUmNTPzdx+q/WvOHW0bgGYLWvWHNT3PTKEQLg0MAQhc0AHASHVHoP/9YytYd4RBVariqno/mEUhVZN98CmD7bg==" }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -9367,18 +19964,6 @@ "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, "util-callbackify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/util-callbackify/-/util-callbackify-1.0.0.tgz", @@ -9402,13 +19987,6 @@ "readable-stream": "^3.0.2", "timeout-refresh": "^1.0.0", "unordered-set": "^2.0.1" - }, - "dependencies": { - "node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" - } } }, "uuid": { @@ -9422,10 +20000,16 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "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==", + "dev": true + }, "v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -9441,15 +20025,11 @@ } } }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } + "vscode-oniguruma": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", + "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==", + "dev": true }, "vscode-textmate": { "version": "5.2.0", @@ -9476,12 +20056,12 @@ } }, "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "requires": { - "makeerror": "1.0.x" + "makeerror": "1.0.12" } }, "webidl-conversions": { @@ -9536,18 +20116,6 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, "wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -9573,11 +20141,48 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } } }, "wrappy": { @@ -9598,10 +20203,11 @@ } }, "ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", @@ -9615,16 +20221,10 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -9636,7 +20236,6 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -9645,13 +20244,29 @@ "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } } }, "yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" }, "yn": { "version": "3.1.1", diff --git a/package.json b/package.json index cf62e9042..29bc7b603 100644 --- a/package.json +++ b/package.json @@ -59,33 +59,36 @@ "scripts": "dist/workers/polykeyWorker.js" }, "scripts": { + "prepare": "tsc -p ./tsconfig.build.json", "build": "rm -r ./dist || true; tsc -p ./tsconfig.build.json", "postbuild": "cp -fR src/proto dist; cp src/notifications/*.json dist/notifications/; cp src/claims/*.json dist/claims/; cp src/status/*.json dist/status/;", "ts-node": "ts-node --require tsconfig-paths/register", "test": "jest", "lint": "eslint '{src,tests}/**/*.{js,ts}'", "lintfix": "eslint '{src,tests}/**/*.{js,ts}' --fix", - "docs": "rm -r ./docs || true; typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src && touch ./docs/.nojekyll", + "docs": "rm -r ./docs || true; typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src", "bench": "rm -r ./benches/results || true; ts-node --require tsconfig-paths/register --compiler typescript-cached-transpile --transpile-only ./benches", "proto-generate": "scripts/proto-generate.sh", "polykey": "ts-node --require tsconfig-paths/register --compiler typescript-cached-transpile --transpile-only src/bin/polykey.ts" }, "dependencies": { - "@grpc/grpc-js": "1.3.7", - "@matrixai/async-init": "^1.6.0", - "@matrixai/db": "^1.1.5", - "@matrixai/id": "^3.3.2", - "@matrixai/logger": "^2.1.0", - "@matrixai/workers": "^1.2.5", + "@grpc/grpc-js": "1.6.7", + "@matrixai/async-init": "^1.7.3", + "@matrixai/async-locks": "^2.2.4", + "@matrixai/db": "^3.3.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/id": "^3.3.3", + "@matrixai/logger": "^2.1.1", + "@matrixai/resources": "^1.1.3", + "@matrixai/workers": "^1.3.3", "ajv": "^7.0.4", - "async-mutex": "^0.3.2", "bip39": "^3.0.3", "canonicalize": "^1.0.5", "cheerio": "^1.0.0-rc.5", "commander": "^8.3.0", "cross-fetch": "^3.0.6", "cross-spawn": "^7.0.3", - "encryptedfs": "^3.4.3", + "encryptedfs": "^3.5.1", "fast-fuzzy": "^1.10.8", "fd-lock": "^1.2.0", "google-protobuf": "^3.14.0", @@ -100,7 +103,6 @@ "readable-stream": "^3.6.0", "resource-counter": "^1.2.4", "threads": "^1.6.5", - "ts-custom-error": "^3.2.0", "utp-native": "^2.5.3", "uuid": "^8.3.0" }, @@ -108,35 +110,34 @@ "@babel/preset-env": "^7.13.10", "@types/cross-spawn": "^6.0.2", "@types/google-protobuf": "^3.7.4", - "@types/jest": "^26.0.20", + "@types/jest": "^27.0.2", "@types/nexpect": "^0.4.31", - "@types/node": "^14.14.35", + "@types/node": "^16.11.7", "@types/node-forge": "^0.9.7", "@types/pako": "^1.0.2", "@types/prompts": "^2.0.13", "@types/readable-stream": "^2.3.11", "@types/uuid": "^8.3.0", - "@typescript-eslint/eslint-plugin": "^5.4.0", - "@typescript-eslint/parser": "^5.4.0", - "babel-jest": "^26.6.3", - "eslint": "^7.17.0", - "eslint-config-prettier": "^7.1.0", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-prettier": "^3.3.1", + "@typescript-eslint/eslint-plugin": "^5.23.0", + "@typescript-eslint/parser": "^5.23.0", + "babel-jest": "^27.0.0", + "eslint": "^8.15.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-prettier": "^4.0.0", "grpc_tools_node_protoc_ts": "^5.1.3", - "jest": "^26.6.3", + "jest": "^27.2.5", "jest-mock-process": "^1.4.1", "jest-mock-props": "^1.9.0", "mocked-env": "^1.3.5", "nexpect": "^0.6.0", - "node-gyp-build": "4.2.3", - "pkg": "5.3.0", - "prettier": "^2.2.1", - "ts-jest": "^26.4.4", + "node-gyp-build": "4.4.0", + "pkg": "5.6.0", + "prettier": "^2.6.2", + "ts-jest": "^27.0.5", "ts-node": "^10.4.0", "tsconfig-paths": "^3.9.0", - "typedoc": "^0.21.5", - "typescript": "^4.1.3", - "typescript-cached-transpile": "0.0.6" + "typedoc": "^0.22.15", + "typescript": "^4.5.2" } } diff --git a/pkgs.nix b/pkgs.nix index 4b5b0c11b..6fe22a5b7 100644 --- a/pkgs.nix +++ b/pkgs.nix @@ -1,4 +1,4 @@ import ( - let rev = "53caacaf56640d04180775aee016d2f16d6f083c"; in - fetchTarball "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz" + let rev = "a5774e76bb8c3145eac524be62375c937143b80c"; in + builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz" ) diff --git a/release.nix b/release.nix index c806c1fc5..e778a0073 100644 --- a/release.nix +++ b/release.nix @@ -18,7 +18,7 @@ let buildPhase = '' cp ${./package.json} package.json pkg . \ - --targets linux-${arch} \ + --targets node${utils.nodeVersion}-linux-${arch} \ --no-bytecode \ --public \ --public-packages "*" \ @@ -44,7 +44,7 @@ let buildPhase = '' cp ${./package.json} package.json pkg . \ - --targets win-${arch} \ + --targets node${utils.nodeVersion}-win-${arch} \ --no-bytecode \ --public \ --public-packages "*" \ @@ -70,7 +70,7 @@ let buildPhase = '' cp ${./package.json} package.json pkg . \ - --targets macos-${arch} \ + --targets node${utils.nodeVersion}-macos-${arch} \ --no-bytecode \ --public \ --public-packages "*" \ diff --git a/shell.nix b/shell.nix index 318d807aa..3b4bd595f 100644 --- a/shell.nix +++ b/shell.nix @@ -7,7 +7,7 @@ in pkgs.mkShell { nativeBuildInputs = [ nodejs - nodePackages.node2nix + utils.node2nix grpc-tools grpcurl utils.pkg @@ -21,9 +21,9 @@ in set +o allexport set -v - # Enables npm link to work - export npm_config_prefix=~/.npm + mkdir --parents "$(pwd)/tmp" + # Built executables and NPM executables export PATH="$(pwd)/dist/bin:$(npm bin):$PATH" # pkg is installed in package.json @@ -34,8 +34,10 @@ in ] }:$PATH" + # Enables npm link to work + export npm_config_prefix=~/.npm + npm install - mkdir --parents "$(pwd)/tmp" set +v ''; diff --git a/src/ErrorPolykey.ts b/src/ErrorPolykey.ts index 414b95732..b7286859e 100644 --- a/src/ErrorPolykey.ts +++ b/src/ErrorPolykey.ts @@ -1,24 +1,41 @@ -import type { POJO } from './types'; -import { CustomError } from 'ts-custom-error'; +import type { Class } from '@matrixai/errors'; +import { AbstractError } from '@matrixai/errors'; import sysexits from './utils/sysexits'; -class ErrorPolykey extends CustomError { - data: POJO; - description: string = 'Polykey error'; +class ErrorPolykey extends AbstractError { + static description: string = 'Polykey error'; exitCode: number = sysexits.GENERAL; - constructor(message: string = '', data: POJO = {}) { - super(message); - this.data = data; - } - toJSON(): string { - return JSON.stringify({ - name: this.name, - description: this.description, - message: this.message, - exitCode: this.exitCode, - data: this.data, - stack: this.stack, + + public static fromJSON>( + this: T, + json: any, + ): InstanceType { + if ( + typeof json !== 'object' || + json.type !== this.name || + typeof json.data !== 'object' || + typeof json.data.message !== 'string' || + isNaN(Date.parse(json.data.timestamp)) || + typeof json.data.data !== 'object' || + typeof json.data.exitCode !== 'number' || + ('stack' in json.data && typeof json.data.stack !== 'string') + ) { + throw new TypeError(`Cannot decode JSON to ${this.name}`); + } + const e = new this(json.data.message, { + timestamp: new Date(json.data.timestamp), + data: json.data.data, + cause: json.data.cause, }); + e.exitCode = json.data.exitCode; + e.stack = json.data.stack; + return e; + } + + public toJSON(): any { + const json = super.toJSON(); + json.data.exitCode = this.exitCode; + return json; } } diff --git a/src/PolykeyAgent.ts b/src/PolykeyAgent.ts index ba9cafc37..68e3b5571 100644 --- a/src/PolykeyAgent.ts +++ b/src/PolykeyAgent.ts @@ -8,27 +8,31 @@ import process from 'process'; import Logger from '@matrixai/logger'; import { DB } from '@matrixai/db'; import { CreateDestroyStartStop } from '@matrixai/async-init/dist/CreateDestroyStartStop'; -import { KeyManager, utils as keysUtils } from './keys'; -import { Status } from './status'; -import { Schema } from './schema'; -import { VaultManager } from './vaults'; -import { ACL } from './acl'; -import { NodeConnectionManager, NodeGraph, NodeManager } from './nodes'; -import * as nodesUtils from './nodes/utils'; -import { NotificationsManager } from './notifications'; -import { GestaltGraph } from './gestalts'; -import { Sigchain } from './sigchain'; -import { Discovery } from './discovery'; -import { SessionManager } from './sessions'; -import { GRPCServer } from './grpc'; -import { IdentitiesManager, providers } from './identities'; +import KeyManager from './keys/KeyManager'; +import Status from './status/Status'; +import Schema from './schema/Schema'; +import VaultManager from './vaults/VaultManager'; +import ACL from './acl/ACL'; +import NodeManager from './nodes/NodeManager'; +import NodeGraph from './nodes/NodeGraph'; +import NodeConnectionManager from './nodes/NodeConnectionManager'; +import NotificationsManager from './notifications/NotificationsManager'; +import GestaltGraph from './gestalts/GestaltGraph'; +import Sigchain from './sigchain/Sigchain'; +import Discovery from './discovery/Discovery'; +import SessionManager from './sessions/SessionManager'; +import GRPCServer from './grpc/GRPCServer'; +import IdentitiesManager from './identities/IdentitiesManager'; +import { providers } from './identities'; import Proxy from './network/Proxy'; import { EventBus, captureRejectionSymbol } from './events'; -import { createAgentService, AgentServiceService } from './agent'; -import { createClientService, ClientServiceService } from './client'; +import createAgentService, { AgentServiceService } from './agent/service'; +import createClientService, { ClientServiceService } from './client/service'; import config from './config'; -import * as utils from './utils'; import * as errors from './errors'; +import * as utils from './utils'; +import * as keysUtils from './keys/utils'; +import * as nodesUtils from './nodes/utils'; type NetworkConfig = { forwardHost?: Host; @@ -417,8 +421,7 @@ class PolykeyAgent { public readonly grpcServerClient: GRPCServer; public readonly events: EventBus; public readonly fs: FileSystem; - - protected logger: Logger; + public readonly logger: Logger; constructor({ nodePath, @@ -546,6 +549,7 @@ class PolykeyAgent { await this.status.start({ pid: process.pid }); await this.schema.start({ fresh }); const agentService = createAgentService({ + db: this.db, keyManager: this.keyManager, vaultManager: this.vaultManager, nodeManager: this.nodeManager, @@ -556,9 +560,11 @@ class PolykeyAgent { acl: this.acl, gestaltGraph: this.gestaltGraph, proxy: this.proxy, + logger: this.logger.getChild(createAgentService.name), }); const clientService = createClientService({ pkAgent: this, + db: this.db, discovery: this.discovery, gestaltGraph: this.gestaltGraph, identitiesManager: this.identitiesManager, @@ -575,6 +581,7 @@ class PolykeyAgent { grpcServerAgent: this.grpcServerAgent, proxy: this.proxy, fs: this.fs, + logger: this.logger.getChild(createClientService.name), }); // Starting modules await this.keyManager.start({ diff --git a/src/acl/ACL.ts b/src/acl/ACL.ts index 358663d51..e97dc6c30 100644 --- a/src/acl/ACL.ts +++ b/src/acl/ACL.ts @@ -1,21 +1,23 @@ +import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; import type { PermissionId, PermissionIdString, Permission, VaultActions, } from './types'; -import type { DB, DBLevel, DBOp } from '@matrixai/db'; import type { NodeId } from '../nodes/types'; import type { GestaltAction } from '../gestalts/types'; import type { VaultAction, VaultId } from '../vaults/types'; import type { Ref } from '../types'; -import { Mutex } from 'async-mutex'; + import Logger from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; +import { utils as dbUtils } from '@matrixai/db'; +import { withF } from '@matrixai/resources'; import * as aclUtils from './utils'; import * as aclErrors from './errors'; @@ -43,15 +45,23 @@ class ACL { protected logger: Logger; protected db: DB; - protected aclDbDomain: string = this.constructor.name; - protected aclPermsDbDomain: Array = [this.aclDbDomain, 'perms']; - protected aclNodesDbDomain: Array = [this.aclDbDomain, 'nodes']; - protected aclVaultsDbDomain: Array = [this.aclDbDomain, 'vaults']; - protected aclDb: DBLevel; - protected aclPermsDb: DBLevel; - protected aclNodesDb: DBLevel; - protected aclVaultsDb: DBLevel; - protected lock: Mutex = new Mutex(); + + protected aclDbPath: LevelPath = [this.constructor.name]; + /** + * Perms stores PermissionId -> Ref + */ + protected aclPermsDbPath: LevelPath = [this.constructor.name, 'perms']; + /** + * Nodes stores NodeId -> PermissionId + */ + protected aclNodesDbPath: LevelPath = [this.constructor.name, 'nodes']; + /** + * Vaults stores VaultIdString -> Record + * note that the NodeId in each record must be in their own unique gestalt + * the NodeId in each record may be missing if it had been previously deleted + */ + protected aclVaultsDbPath: LevelPath = [this.constructor.name, 'vaults']; + protected generatePermId: () => PermissionId; constructor({ db, logger }: { db: DB; logger: Logger }) { @@ -59,32 +69,15 @@ class ACL { this.db = db; } - get locked(): boolean { - return this.lock.isLocked(); - } - public async start({ fresh = false, }: { fresh?: boolean; } = {}): Promise { this.logger.info(`Starting ${this.constructor.name}`); - const aclDb = await this.db.level(this.aclDbDomain); - // Perms stores PermissionId -> Ref - const aclPermsDb = await this.db.level(this.aclPermsDbDomain[1], aclDb); - // Nodes stores NodeId -> PermissionId - const aclNodesDb = await this.db.level(this.aclNodesDbDomain[1], aclDb); - // Vaults stores VaultIdString -> Record - // note that the NodeId in each array must be in their own unique gestalt - // the NodeId in each array may be missing if it had been previously deleted - const aclVaultsDb = await this.db.level(this.aclVaultsDbDomain[1], aclDb); if (fresh) { - await aclDb.clear(); + await this.db.clear(this.aclDbPath); } - this.aclDb = aclDb; - this.aclPermsDb = aclPermsDb; - this.aclNodesDb = aclNodesDb; - this.aclVaultsDb = aclVaultsDb; this.generatePermId = aclUtils.createPermIdGenerator(); this.logger.info(`Started ${this.constructor.name}`); } @@ -96,160 +89,131 @@ class ACL { public async destroy() { this.logger.info(`Destroying ${this.constructor.name}`); - const aclDb = await this.db.level(this.aclDbDomain); - await aclDb.clear(); + await this.db.clear(this.aclDbPath); this.logger.info(`Destroyed ${this.constructor.name}`); } - /** - * Run several operations within the same lock - * This does not ensure atomicity of the underlying database - * Database atomicity still depends on the underlying operation - */ - @ready(new aclErrors.ErrorACLNotRunning()) - public async transaction(f: (acl: ACL) => Promise): Promise { - const release = await this.lock.acquire(); - try { - return await f(this); - } finally { - release(); - } - } - - /** - * Transaction wrapper that will not lock if the operation was executed - * within a transaction context - */ @ready(new aclErrors.ErrorACLNotRunning()) - public async _transaction(f: () => Promise): Promise { - if (this.lock.isLocked()) { - return await f(); - } else { - return await this.transaction(f); - } + public async withTransactionF( + f: (tran: DBTransaction) => Promise, + ): Promise { + return withF([this.db.transaction()], ([tran]) => f(tran)); } @ready(new aclErrors.ErrorACLNotRunning()) public async sameNodePerm( nodeId1: NodeId, nodeId2: NodeId, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const permId1 = await this.db.get( - this.aclNodesDbDomain, - nodeId1.toBuffer(), - true, + if (tran == null) { + return this.withTransactionF(async (tran) => + this.sameNodePerm(nodeId1, nodeId2, tran), ); - const permId2 = await this.db.get( - this.aclNodesDbDomain, - nodeId2.toBuffer(), - true, + } + const permId1 = await tran.get( + [...this.aclNodesDbPath, nodeId1.toBuffer()], + true, + ); + const permId2 = await tran.get( + [...this.aclNodesDbPath, nodeId2.toBuffer()], + true, + ); + if (permId1 != null && permId2 != null) { + return IdInternal.fromBuffer(permId1).equals( + IdInternal.fromBuffer(permId2), ); - if (permId1 != null && permId2 != null && permId1 === permId2) { - return true; - } - return false; - }); + } + return false; } @ready(new aclErrors.ErrorACLNotRunning()) - public async getNodePerms(): Promise>> { - return await this._transaction(async () => { - const permIds: Record< - PermissionIdString, - Record - > = {}; - for await (const o of this.aclNodesDb.createReadStream()) { - const nodeId = IdInternal.fromBuffer((o as any).key); - const data = (o as any).value as Buffer; - const permId = IdInternal.fromBuffer( - await this.db.deserializeDecrypt(data, true), - ); - let nodePerm: Record; - if (permId in permIds) { - nodePerm = permIds[permId]; - // Get the first existing perm object - let perm: Permission; - for (const nodeId_ in nodePerm) { - perm = nodePerm[nodeId_]; - break; - } - // All perm objects are shared - nodePerm[nodeId] = perm!; - } else { - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId.toBuffer(), - )) as Ref; - nodePerm = { [nodeId]: permRef.object }; - permIds[permId] = nodePerm; + public async getNodePerms( + tran?: DBTransaction, + ): Promise>> { + if (tran == null) { + return this.withTransactionF(async (tran) => this.getNodePerms(tran)); + } + const permIds: Record> = {}; + for await (const [k, v] of tran.iterator(undefined, [ + ...this.aclNodesDbPath, + ])) { + const nodeId = IdInternal.fromBuffer(k); + const permId = IdInternal.fromBuffer(v); + let nodePerm: Record; + if (permId in permIds) { + nodePerm = permIds[permId]; + // Get the first existing perm object + let perm: Permission; + for (const nodeId_ in nodePerm) { + perm = nodePerm[nodeId_]; + break; } + // All perm objects are shared + nodePerm[nodeId] = perm!; + } else { + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId.toBuffer()], + false, + )) as Ref; + nodePerm = { [nodeId]: permRef.object }; + permIds[permId] = nodePerm; } - const nodePerms_: Array> = []; - for (const permId in permIds) { - nodePerms_.push(permIds[permId]); - } - return nodePerms_; - }); + } + const nodePerms_: Array> = []; + for (const permId in permIds) { + nodePerms_.push(permIds[permId]); + } + return nodePerms_; } @ready(new aclErrors.ErrorACLNotRunning()) - public async getVaultPerms(): Promise< - Record> - > { - return await this._transaction(async () => { - const vaultPerms: Record> = {}; - const ops: Array = []; - for await (const o of this.aclVaultsDb.createReadStream()) { - const vaultIdBuffer = (o as any).key as Buffer; - const vaultId = IdInternal.fromBuffer(vaultIdBuffer); - const data = (o as any).value as Buffer; - const nodeIds = await this.db.deserializeDecrypt>( - data, - false, + public async getVaultPerms( + tran?: DBTransaction, + ): Promise>> { + if (tran == null) { + return this.withTransactionF(async (tran) => this.getVaultPerms(tran)); + } + const vaultPerms: Record> = {}; + for await (const [k, v] of tran.iterator(undefined, [ + ...this.aclVaultsDbPath, + ])) { + const vaultId = IdInternal.fromBuffer(k); + const nodeIds = dbUtils.deserialize>(v); + const nodePerm: Record = {}; + const nodeIdsGc: Set = new Set(); + for (const nodeIdString in nodeIds) { + const nodeId: NodeId = IdInternal.fromString(nodeIdString); + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, ); - const nodePerm: Record = {}; - const nodeIdsGc: Set = new Set(); - for (const nodeIdString in nodeIds) { - const nodeId: NodeId = IdInternal.fromString(nodeIdString); - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), - true, - ); - if (permId == null) { - // Invalid node id - nodeIdsGc.add(nodeId); - continue; - } - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, - )) as Ref; - if (!(vaultId in permRef.object.vaults)) { - // Vault id is missing from the perm - nodeIdsGc.add(nodeId); - continue; - } - nodePerm[nodeId] = permRef.object; + if (permId == null) { + // Invalid node id + nodeIdsGc.add(nodeId); + continue; + } + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; + if (!(vaultId in permRef.object.vaults)) { + // Vault id is missing from the perm + nodeIdsGc.add(nodeId); + continue; } - if (nodeIdsGc.size > 0) { - // Remove invalid node ids - for (const nodeId of nodeIdsGc) { - delete nodeIds[nodeId]; - } - ops.push({ - type: 'put', - domain: this.aclVaultsDbDomain, - key: vaultId.toBuffer(), - value: nodeIds, - }); + nodePerm[nodeId] = permRef.object; + } + if (nodeIdsGc.size > 0) { + // Remove invalid node ids + for (const nodeId of nodeIdsGc) { + delete nodeIds[nodeId]; } - vaultPerms[vaultId] = nodePerm; + await tran.put([...this.aclVaultsDbPath, vaultId.toBuffer()], nodeIds); } - await this.db.batch(ops); - return vaultPerms; - }); + vaultPerms[vaultId] = nodePerm; + } + return vaultPerms; } /** @@ -257,22 +221,27 @@ class ACL { * Any node id is acceptable */ @ready(new aclErrors.ErrorACLNotRunning()) - public async getNodePerm(nodeId: NodeId): Promise { - return await this._transaction(async () => { - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), - true, + public async getNodePerm( + nodeId: NodeId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getNodePerm(nodeId, tran), ); - if (permId == null) { - return; - } - const perm = (await this.db.get( - this.aclPermsDbDomain, - permId, - )) as Ref; - return perm.object; - }); + } + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, + ); + if (permId == null) { + return; + } + const perm = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; + return perm.object; } /** @@ -283,127 +252,128 @@ class ACL { @ready(new aclErrors.ErrorACLNotRunning()) public async getVaultPerm( vaultId: VaultId, + tran?: DBTransaction, ): Promise> { - return await this._transaction(async () => { - const nodeIds = await this.db.get>( - this.aclVaultsDbDomain, - vaultId.toBuffer(), + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getVaultPerm(vaultId, tran), ); - if (nodeIds == null) { - return {}; + } + const nodeIds = await tran.get>( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, + ); + if (nodeIds == null) { + return {}; + } + const perms: Record = {}; + const nodeIdsGc: Set = new Set(); + for (const nodeIdString in nodeIds) { + const nodeId: NodeId = IdInternal.fromString(nodeIdString); + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, + ); + if (permId == null) { + // Invalid node id + nodeIdsGc.add(nodeId); + continue; } - const perms: Record = {}; - const nodeIdsGc: Set = new Set(); - for (const nodeIdString in nodeIds) { - const nodeId: NodeId = IdInternal.fromString(nodeIdString); - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), - true, - ); - if (permId == null) { - // Invalid node id - nodeIdsGc.add(nodeId); - continue; - } - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, - )) as Ref; - if (!(vaultId in permRef.object.vaults)) { - // Vault id is missing from the perm - nodeIdsGc.add(nodeId); - continue; - } - perms[nodeId] = permRef.object; + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; + if (!(vaultId in permRef.object.vaults)) { + // Vault id is missing from the perm + nodeIdsGc.add(nodeId); + continue; } - if (nodeIdsGc.size > 0) { - // Remove invalid node ids - for (const nodeId of nodeIdsGc) { - delete nodeIds[nodeId]; - } - await this.db.put(this.aclVaultsDbDomain, vaultId.toBuffer(), nodeIds); + perms[nodeId] = permRef.object; + } + if (nodeIdsGc.size > 0) { + // Remove invalid node ids + for (const nodeId of nodeIdsGc) { + delete nodeIds[nodeId]; } - return perms; - }); + await tran.put( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + nodeIds, + false, + ); + } + return perms; } @ready(new aclErrors.ErrorACLNotRunning()) public async setNodeAction( nodeId: NodeId, action: GestaltAction, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), - true, + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setNodeAction(nodeId, action, tran), ); - const ops: Array = []; - if (permId == null) { - const permId = await this.generatePermId(); - const permRef = { - count: 1, - object: { - gestalt: { - [action]: null, - }, - vaults: {}, - }, - }; - ops.push( - { - type: 'put', - domain: this.aclPermsDbDomain, - key: permId.toBuffer(), - value: permRef, - }, - { - type: 'put', - domain: this.aclNodesDbDomain, - key: nodeId.toBuffer(), - value: permId.toBuffer(), - raw: true, + } + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, + ); + if (permId == null) { + const permId = this.generatePermId(); + const permRef = { + count: 1, + object: { + gestalt: { + [action]: null, }, - ); - } else { - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, - )) as Ref; - permRef.object.gestalt[action] = null; - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: permRef, - }); - } - await this.db.batch(ops); - }); + vaults: {}, + }, + }; + await tran.put( + [...this.aclPermsDbPath, permId.toBuffer()], + permRef, + false, + ); + await tran.put( + [...this.aclNodesDbPath, nodeId.toBuffer()], + permId.toBuffer(), + true, + ); + } else { + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; + permRef.object.gestalt[action] = null; + await tran.put([...this.aclPermsDbPath, permId], permRef, false); + } } @ready(new aclErrors.ErrorACLNotRunning()) public async unsetNodeAction( nodeId: NodeId, action: GestaltAction, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), - true, + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetNodeAction(nodeId, action, tran), ); - if (permId == null) { - return; - } - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, - )) as Ref; - delete permRef.object.gestalt[action]; - await this.db.put(this.aclPermsDbDomain, permId, permRef); - }); + } + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, + ); + if (permId == null) { + return; + } + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; + delete permRef.object.gestalt[action]; + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -411,55 +381,43 @@ class ACL { vaultId: VaultId, nodeId: NodeId, action: VaultAction, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const nodeIds = - (await this.db.get>( - this.aclVaultsDbDomain, - vaultId.toBuffer(), - )) ?? {}; - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), - true, + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setVaultAction(vaultId, nodeId, action, tran), ); - if (permId == null) { - throw new aclErrors.ErrorACLNodeIdMissing(); - } - nodeIds[nodeId] = null; - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, - )) as Ref; - let actions: VaultActions | undefined = permRef.object.vaults[vaultId]; - if (actions == null) { - actions = {}; - permRef.object.vaults[vaultId] = actions; - } - actions[action] = null; - const ops: Array = [ - { - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: permRef, - }, - { - type: 'put', - domain: this.aclNodesDbDomain, - key: nodeId.toBuffer(), - value: permId, - raw: true, - }, - { - type: 'put', - domain: this.aclVaultsDbDomain, - key: vaultId.toBuffer(), - value: nodeIds, - }, - ]; - await this.db.batch(ops); - }); + } + const nodeIds = + (await tran.get>( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, + )) ?? {}; + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, + ); + if (permId == null) { + throw new aclErrors.ErrorACLNodeIdMissing(); + } + nodeIds[nodeId] = null; + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; + let actions: VaultActions | undefined = permRef.object.vaults[vaultId]; + if (actions == null) { + actions = {}; + permRef.object.vaults[vaultId] = actions; + } + actions[action] = null; + await tran.put([...this.aclPermsDbPath, permId], permRef, false); + await tran.put([...this.aclNodesDbPath, nodeId.toBuffer()], permId, true); + await tran.put( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + nodeIds, + false, + ); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -467,34 +425,37 @@ class ACL { vaultId: VaultId, nodeId: NodeId, action: VaultAction, + tran?: DBTransaction, ): Promise { - await this._transaction(async () => { - const nodeIds = await this.db.get>( - this.aclVaultsDbDomain, - vaultId.toBuffer(), - ); - if (nodeIds == null || !(nodeId in nodeIds)) { - return; - } - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), - true, + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetVaultAction(vaultId, nodeId, action, tran), ); - if (permId == null) { - return; - } - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, - )) as Ref; - const actions: VaultActions | undefined = permRef.object.vaults[vaultId]; - if (actions == null) { - return; - } - delete actions[action]; - await this.db.put(this.aclPermsDbDomain, permId, permRef); - }); + } + const nodeIds = await tran.get>( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, + ); + if (nodeIds == null || !(nodeId in nodeIds)) { + return; + } + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, + ); + if (permId == null) { + return; + } + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; + const actions: VaultActions | undefined = permRef.object.vaults[vaultId]; + if (actions == null) { + return; + } + delete actions[action]; + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } /** @@ -506,24 +467,17 @@ class ACL { public async setNodesPerm( nodeIds: Array, perm: Permission, + tran?: DBTransaction, ): Promise { - await this._transaction(async () => { - const ops = await this.setNodesPermOps(nodeIds, perm); - await this.db.batch(ops); - }); - } - - @ready(new aclErrors.ErrorACLNotRunning()) - public async setNodesPermOps( - nodeIds: Array, - perm: Permission, - ): Promise> { - const ops: Array = []; + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setNodesPerm(nodeIds, perm, tran), + ); + } const permIdCounts: Record = {}; for (const nodeId of nodeIds) { - const permIdBuffer = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), + const permIdBuffer = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permIdBuffer == null) { @@ -534,196 +488,146 @@ class ACL { } for (const permIdString in permIdCounts) { const permId = IdInternal.fromString(permIdString); - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId.toBuffer(), + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId.toBuffer()], + false, )) as Ref; permRef.count = permRef.count - permIdCounts[permId]; if (permRef.count === 0) { - ops.push({ - type: 'del', - domain: this.aclPermsDbDomain, - key: permId.toBuffer(), - }); + await tran.del([...this.aclPermsDbPath, permId.toBuffer()]); } else { - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId.toBuffer(), - value: permRef, - }); + await tran.put( + [...this.aclPermsDbPath, permId.toBuffer()], + permRef, + false, + ); } } - const permId = await this.generatePermId(); + const permId = this.generatePermId(); const permRef = { count: nodeIds.length, object: perm, }; - ops.push({ - domain: this.aclPermsDbDomain, - type: 'put', - key: permId.toBuffer(), - value: permRef, - }); + await tran.put([...this.aclPermsDbPath, permId.toBuffer()], permRef, false); for (const nodeId of nodeIds) { - ops.push({ - domain: this.aclNodesDbDomain, - type: 'put', - key: nodeId.toBuffer(), - value: permId.toBuffer(), - raw: true, - }); - } - return ops; - } - - @ready(new aclErrors.ErrorACLNotRunning()) - public async setNodePerm(nodeId: NodeId, perm: Permission): Promise { - await this._transaction(async () => { - const ops = await this.setNodePermOps(nodeId, perm); - await this.db.batch(ops); - }); + await tran.put( + [...this.aclNodesDbPath, nodeId.toBuffer()], + permId.toBuffer(), + true, + ); + } } @ready(new aclErrors.ErrorACLNotRunning()) - public async setNodePermOps( + public async setNodePerm( nodeId: NodeId, perm: Permission, - ): Promise> { - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setNodePerm(nodeId, perm, tran), + ); + } + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); - const ops: Array = []; if (permId == null) { - const permId = await this.generatePermId(); + const permId = this.generatePermId(); const permRef = { count: 1, object: perm, }; - ops.push( - { - type: 'put', - domain: this.aclPermsDbDomain, - key: permId.toBuffer(), - value: permRef, - }, - { - type: 'put', - domain: this.aclNodesDbDomain, - key: nodeId.toBuffer(), - value: permId.toBuffer(), - raw: true, - }, + await tran.put( + [...this.aclPermsDbPath, permId.toBuffer()], + permRef, + false, + ); + await tran.put( + [...this.aclNodesDbPath, nodeId.toBuffer()], + permId.toBuffer(), + true, ); } else { // The entire gestalt's perm gets replaced, therefore the count stays the same - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, )) as Ref; permRef.object = perm; - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: permRef, - }); - } - return ops; - } - - @ready(new aclErrors.ErrorACLNotRunning()) - public async unsetNodePerm(nodeId: NodeId): Promise { - await this._transaction(async () => { - const ops = await this.unsetNodePermOps(nodeId); - await this.db.batch(ops); - }); + await tran.put([...this.aclPermsDbPath, permId], permRef, false); + } } @ready(new aclErrors.ErrorACLNotRunning()) - public async unsetNodePermOps(nodeId: NodeId): Promise> { - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), + public async unsetNodePerm( + nodeId: NodeId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetNodePerm(nodeId, tran), + ); + } + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { - return []; + return; } - const ops: Array = []; - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, )) as Ref; const count = --permRef.count; if (count === 0) { - ops.push({ - type: 'del', - domain: this.aclPermsDbDomain, - key: permId, - }); + await tran.del([...this.aclPermsDbPath, permId]); } else { - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: permRef, - }); - } - ops.push({ - type: 'del', - domain: this.aclNodesDbDomain, - key: nodeId.toBuffer(), - }); + await tran.put([...this.aclPermsDbPath, permId], permRef, false); + } + await tran.del([...this.aclNodesDbPath, nodeId.toBuffer()]); // We do not remove the node id from the vaults // they can be removed later upon inspection - return ops; } @ready(new aclErrors.ErrorACLNotRunning()) - public async unsetVaultPerms(vaultId: VaultId): Promise { - await this._transaction(async () => { - const nodeIds = await this.db.get>( - this.aclVaultsDbDomain, - vaultId.toBuffer(), + public async unsetVaultPerms( + vaultId: VaultId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetVaultPerms(vaultId, tran), ); - if (nodeIds == null) { - return; - } - const ops: Array = []; - for (const nodeIdString in nodeIds) { - const nodeId: NodeId = IdInternal.fromString(nodeIdString); - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), - true, - ); - // Skip if the nodeId doesn't exist - // this means that it previously been removed - if (permId == null) { - continue; - } - const perm = (await this.db.get( - this.aclPermsDbDomain, - permId, - )) as Ref; - delete perm.object.vaults[vaultId]; - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: perm, - }); + } + const nodeIds = await tran.get>( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, + ); + if (nodeIds == null) { + return; + } + for (const nodeIdString in nodeIds) { + const nodeId: NodeId = IdInternal.fromString(nodeIdString); + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, + ); + // Skip if the nodeId doesn't exist + // this means that it previously been removed + if (permId == null) { + continue; } - ops.push({ - type: 'del', - domain: this.aclVaultsDbDomain, - key: vaultId.toBuffer(), - }); - await this.db.batch(ops); - }); + const perm = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; + delete perm.object.vaults[vaultId]; + await tran.put([...this.aclPermsDbPath, permId], perm, false); + } + await tran.del([...this.aclVaultsDbPath, vaultId.toBuffer()]); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -731,40 +635,31 @@ class ACL { nodeId: NodeId, nodeIdsJoin: Array, perm?: Permission, + tran?: DBTransaction, ): Promise { - await this._transaction(async () => { - const ops = await this.joinNodePermOps(nodeId, nodeIdsJoin, perm); - await this.db.batch(ops); - }); - } - - @ready(new aclErrors.ErrorACLNotRunning()) - public async joinNodePermOps( - nodeId: NodeId, - nodeIdsJoin: Array, - perm?: Permission, - ): Promise> { - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), + if (tran == null) { + return this.withTransactionF(async (tran) => + this.joinNodePerm(nodeId, nodeIdsJoin, perm, tran), + ); + } + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { throw new aclErrors.ErrorACLNodeIdMissing(); } - const ops: Array = []; - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, )) as Ref; // Optionally replace the permission record for the target if (perm != null) { permRef.object = perm; } for (const nodeIdJoin of nodeIdsJoin) { - const permIdJoin = await this.db.get( - this.aclNodesDbDomain, - nodeIdJoin.toBuffer(), + const permIdJoin = await tran.get( + [...this.aclNodesDbPath, nodeIdJoin.toBuffer()], true, ); if (permIdJoin === permId) { @@ -772,73 +667,49 @@ class ACL { } ++permRef.count; if (permIdJoin != null) { - const permJoin = (await this.db.get( - this.aclPermsDbDomain, - permIdJoin, + const permJoin = (await tran.get( + [...this.aclPermsDbPath, permIdJoin], + false, )) as Ref; --permJoin.count; if (permJoin.count === 0) { - ops.push({ - type: 'del', - domain: this.aclPermsDbDomain, - key: permIdJoin, - }); + await tran.del([...this.aclPermsDbPath, permIdJoin]); } else { - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permIdJoin, - value: permJoin, - }); + await tran.put([...this.aclPermsDbPath, permIdJoin], permJoin, false); } } - ops.push({ - type: 'put', - domain: this.aclNodesDbDomain, - key: nodeIdJoin.toBuffer(), - value: permId, - raw: true, - }); - } - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: permRef, - }); - return ops; + await tran.put( + [...this.aclNodesDbPath, nodeIdJoin.toBuffer()], + permId, + true, + ); + } + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } @ready(new aclErrors.ErrorACLNotRunning()) public async joinVaultPerms( vaultId: VaultId, vaultIdsJoin: Array, + tran?: DBTransaction, ): Promise { - await this._transaction(async () => { - const ops = await this.joinVaultPermsOps(vaultId, vaultIdsJoin); - await this.db.batch(ops); - }); - } - - @ready(new aclErrors.ErrorACLNotRunning()) - private async joinVaultPermsOps( - vaultId: VaultId, - vaultIdsJoin: Array, - ): Promise> { - const nodeIds = await this.db.get>( - this.aclVaultsDbDomain, - vaultId.toBuffer(), + if (tran == null) { + return this.withTransactionF(async (tran) => + this.joinVaultPerms(vaultId, vaultIdsJoin, tran), + ); + } + const nodeIds = await tran.get>( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, ); if (nodeIds == null) { throw new aclErrors.ErrorACLVaultIdMissing(); } - const ops: Array = []; const nodeIdsGc: Set = new Set(); for (const nodeIdString in nodeIds) { const nodeId: NodeId = IdInternal.fromString(nodeIdString); - const permId = await this.db.get( - this.aclNodesDbDomain, - nodeId.toBuffer(), + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { @@ -846,9 +717,9 @@ class ACL { nodeIdsGc.add(nodeId); continue; } - const permRef = (await this.db.get( - this.aclPermsDbDomain, - permId, + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, )) as Ref; if (!(vaultId in permRef.object.vaults)) { // Vault id is missing from the perm @@ -860,34 +731,26 @@ class ACL { for (const vaultIdJoin of vaultIdsJoin) { permRef.object.vaults[vaultIdJoin] = vaultActions; } - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: permRef, - }); + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } for (const vaultIdJoin of vaultIdsJoin) { - ops.push({ - type: 'put', - domain: this.aclVaultsDbDomain, - key: vaultIdJoin.toBuffer(), - value: nodeIds, - }); + await tran.put( + [...this.aclVaultsDbPath, vaultIdJoin.toBuffer()], + nodeIds, + false, + ); } if (nodeIdsGc.size > 0) { // Remove invalid node ids for (const nodeId of nodeIdsGc) { delete nodeIds[nodeId]; } - ops.push({ - type: 'put', - domain: this.aclVaultsDbDomain, - key: vaultId.toBuffer(), - value: nodeIds, - }); - } - return ops; + await tran.put( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + nodeIds, + false, + ); + } } } diff --git a/src/acl/errors.ts b/src/acl/errors.ts index f22044397..508513759 100644 --- a/src/acl/errors.ts +++ b/src/acl/errors.ts @@ -1,18 +1,36 @@ -import { ErrorPolykey } from '../errors'; - -class ErrorACL extends ErrorPolykey {} - -class ErrorACLRunning extends ErrorACL {} - -class ErrorACLNotRunning extends ErrorACL {} - -class ErrorACLDestroyed extends ErrorACL {} - -class ErrorACLNodeIdMissing extends ErrorACL {} - -class ErrorACLVaultIdMissing extends ErrorACL {} - -class ErrorACLNodeIdExists extends ErrorACL {} +import { ErrorPolykey, sysexits } from '../errors'; + +class ErrorACL extends ErrorPolykey {} + +class ErrorACLRunning extends ErrorACL { + static description = 'ACL is running'; + exitCode = sysexits.USAGE; +} + +class ErrorACLNotRunning extends ErrorACL { + static description = 'ACL is not running'; + exitCode = sysexits.USAGE; +} + +class ErrorACLDestroyed extends ErrorACL { + static description = 'ACL is destroyed'; + exitCode = sysexits.USAGE; +} + +class ErrorACLNodeIdMissing extends ErrorACL { + static description = 'Could not find NodeId'; + exitCode = sysexits.NOUSER; +} + +class ErrorACLVaultIdMissing extends ErrorACL { + static description = 'Could not find VaultId'; + exitCode = sysexits.DATAERR; +} + +class ErrorACLNodeIdExists extends ErrorACL { + static description = 'NodeId already exists'; + exitCode = sysexits.DATAERR; +} export { ErrorACL, diff --git a/src/agent/GRPCClientAgent.ts b/src/agent/GRPCClientAgent.ts index 4190f66b6..bfc1c4d65 100644 --- a/src/agent/GRPCClientAgent.ts +++ b/src/agent/GRPCClientAgent.ts @@ -79,6 +79,11 @@ class GRPCClientAgent extends GRPCClient { public echo(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.echo, )(...args); } @@ -92,6 +97,11 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsGitInfoGet, )(...args); } @@ -106,6 +116,11 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyDuplexStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsGitPackGet, )(...args); } @@ -119,6 +134,11 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsScan, )(...args); } @@ -127,6 +147,11 @@ class GRPCClientAgent extends GRPCClient { public nodesClosestLocalNodesGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesClosestLocalNodesGet, )(...args); } @@ -135,6 +160,11 @@ class GRPCClientAgent extends GRPCClient { public nodesClaimsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesClaimsGet, )(...args); } @@ -143,6 +173,11 @@ class GRPCClientAgent extends GRPCClient { public nodesChainDataGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesChainDataGet, )(...args); } @@ -151,6 +186,11 @@ class GRPCClientAgent extends GRPCClient { public nodesHolePunchMessageSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesHolePunchMessageSend, )(...args); } @@ -159,6 +199,11 @@ class GRPCClientAgent extends GRPCClient { public notificationsSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.notificationsSend, )(...args); } @@ -176,6 +221,11 @@ class GRPCClientAgent extends GRPCClient { nodesPB.CrossSign >( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesCrossSignClaim, )(...args); } diff --git a/src/agent/errors.ts b/src/agent/errors.ts index e4db4293c..b0460055c 100644 --- a/src/agent/errors.ts +++ b/src/agent/errors.ts @@ -1,15 +1,24 @@ import { ErrorPolykey, sysexits } from '../errors'; -class ErrorAgent extends ErrorPolykey {} +class ErrorAgent extends ErrorPolykey {} -class ErrorAgentRunning extends ErrorPolykey {} +class ErrorAgentRunning extends ErrorPolykey { + static description = 'Agent Client is running'; + exitCode = sysexits.USAGE; +} -class ErrorAgentClientNotStarted extends ErrorAgent {} +class ErrorAgentClientNotStarted extends ErrorAgent { + static description = 'Agent Client is not started'; + exitCode = sysexits.USAGE; +} -class ErrorAgentClientDestroyed extends ErrorAgent {} +class ErrorAgentClientDestroyed extends ErrorAgent { + static description = 'Agent Client is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorConnectionInfoMissing extends ErrorAgent { - description = 'Vault already exists'; +class ErrorConnectionInfoMissing extends ErrorAgent { + static description = 'Vault already exists'; exitCode = sysexits.UNAVAILABLE; } diff --git a/src/agent/service/index.ts b/src/agent/service/index.ts index aa96bfd2e..6342c2ba5 100644 --- a/src/agent/service/index.ts +++ b/src/agent/service/index.ts @@ -1,16 +1,16 @@ -import type { KeyManager } from '../../keys'; -import type { VaultManager } from '../../vaults'; -import type { - NodeGraph, - NodeManager, - NodeConnectionManager, -} from '../../nodes'; -import type { NotificationsManager } from '../../notifications'; -import type { Sigchain } from '../../sigchain'; -import type { ACL } from '../../acl'; -import type { GestaltGraph } from '../../gestalts'; +import type { DB } from '@matrixai/db'; +import type KeyManager from '../../keys/KeyManager'; +import type VaultManager from '../../vaults/VaultManager'; +import type NodeGraph from '../../nodes/NodeGraph'; +import type NodeManager from '../../nodes/NodeManager'; +import type NodeConnectionManager from '../../nodes/NodeConnectionManager'; +import type NotificationsManager from '../../notifications/NotificationsManager'; +import type Sigchain from '../../sigchain/Sigchain'; +import type ACL from '../../acl/ACL'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { IAgentServiceServer } from '../../proto/js/polykey/v1/agent_service_grpc_pb'; import type Proxy from '../../network/Proxy'; +import Logger from '@matrixai/logger'; import echo from './echo'; import nodesChainDataGet from './nodesChainDataGet'; import nodesClaimsGet from './nodesClaimsGet'; @@ -24,7 +24,13 @@ import vaultsScan from './vaultsScan'; import { AgentServiceService } from '../../proto/js/polykey/v1/agent_service_grpc_pb'; import * as agentUtils from '../utils'; -function createService(container: { +function createService({ + proxy, + db, + logger = new Logger(createService.name), + ...containerRest +}: { + db: DB; keyManager: KeyManager; vaultManager: VaultManager; nodeConnectionManager: NodeConnectionManager; @@ -35,23 +41,26 @@ function createService(container: { acl: ACL; gestaltGraph: GestaltGraph; proxy: Proxy; + logger?: Logger; }): IAgentServiceServer { - const connectionInfoGet = agentUtils.connectionInfoGetter(container.proxy); - const container_ = { - ...container, + const connectionInfoGet = agentUtils.connectionInfoGetter(proxy); + const container = { + ...containerRest, + db, + logger, connectionInfoGet: connectionInfoGet, }; const service: IAgentServiceServer = { - echo: echo(container_), - nodesChainDataGet: nodesChainDataGet(container_), - nodesClaimsGet: nodesClaimsGet(container_), - nodesClosestLocalNodesGet: nodesClosestLocalNodesGet(container_), - nodesCrossSignClaim: nodesCrossSignClaim(container_), - nodesHolePunchMessageSend: nodesHolePunchMessageSend(container_), - notificationsSend: notificationsSend(container_), - vaultsGitInfoGet: vaultsGitInfoGet(container_), - vaultsGitPackGet: vaultsGitPackGet(container_), - vaultsScan: vaultsScan(container_), + echo: echo(container), + nodesChainDataGet: nodesChainDataGet(container), + nodesClaimsGet: nodesClaimsGet(container), + nodesClosestLocalNodesGet: nodesClosestLocalNodesGet(container), + nodesCrossSignClaim: nodesCrossSignClaim(container), + nodesHolePunchMessageSend: nodesHolePunchMessageSend(container), + notificationsSend: notificationsSend(container), + vaultsGitInfoGet: vaultsGitInfoGet(container), + vaultsGitPackGet: vaultsGitPackGet(container), + vaultsScan: vaultsScan(container), }; return service; } diff --git a/src/agent/service/nodesChainDataGet.ts b/src/agent/service/nodesChainDataGet.ts index 3ed37b99f..492c8ca73 100644 --- a/src/agent/service/nodesChainDataGet.ts +++ b/src/agent/service/nodesChainDataGet.ts @@ -1,21 +1,33 @@ import type * as grpc from '@grpc/grpc-js'; -import type { Sigchain } from '../../sigchain'; +import type { DB } from '@matrixai/db'; +import type Sigchain from '../../sigchain/Sigchain'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; import type { ClaimIdEncoded } from '../../claims/types'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; /** * Retrieves the ChainDataEncoded of this node. */ -function nodesChainDataGet({ sigchain }: { sigchain: Sigchain }) { +function nodesChainDataGet({ + sigchain, + db, + logger, +}: { + sigchain: Sigchain; + db: DB; + logger: Logger; +}) { return async ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise => { try { const response = new nodesPB.ChainData(); - const chainData = await sigchain.getChainData(); + const chainData = await db.withTransactionF(async (tran) => + sigchain.getChainData(tran), + ); // Iterate through each claim in the chain, and serialize for transport let claimIdEncoded: ClaimIdEncoded; for (claimIdEncoded in chainData) { @@ -37,7 +49,8 @@ function nodesChainDataGet({ sigchain }: { sigchain: Sigchain }) { callback(null, response); return; } catch (e) { - callback(grpcUtils.fromError(e)); + callback(grpcUtils.fromError(e, true)); + logger.error(e); return; } }; diff --git a/src/agent/service/nodesClosestLocalNodesGet.ts b/src/agent/service/nodesClosestLocalNodesGet.ts index 559337c9d..bd562bbe5 100644 --- a/src/agent/service/nodesClosestLocalNodesGet.ts +++ b/src/agent/service/nodesClosestLocalNodesGet.ts @@ -1,9 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; -import type { NodeConnectionManager } from '../../nodes'; +import type { DB } from '@matrixai/db'; +import type NodeConnectionManager from '../../nodes/NodeConnectionManager'; import type { NodeId } from '../../nodes/types'; -import { utils as grpcUtils } from '../../grpc'; -import { utils as nodesUtils } from '../../nodes'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import * as nodesUtils from '../../nodes/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; @@ -13,8 +16,12 @@ import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; */ function nodesClosestLocalNodesGet({ nodeConnectionManager, + db, + logger, }: { nodeConnectionManager: NodeConnectionManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -38,8 +45,13 @@ function nodesClosestLocalNodesGet({ }, ); // Get all local nodes that are closest to the target node from the request - const closestNodes = await nodeConnectionManager.getClosestLocalNodes( - nodeId, + const closestNodes = await db.withTransactionF( + async (tran) => + await nodeConnectionManager.getClosestLocalNodes( + nodeId, + undefined, + tran, + ), ); for (const node of closestNodes) { const addressMessage = new nodesPB.Address(); @@ -53,7 +65,8 @@ function nodesClosestLocalNodesGet({ callback(null, response); return; } catch (e) { - callback(grpcUtils.fromError(e)); + callback(grpcUtils.fromError(e, true)); + logger.error(e); return; } }; diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index 907494512..f0a3e2a9a 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -1,33 +1,40 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { ClaimEncoded, ClaimIntermediary } from '../../claims/types'; -import type { NodeManager } from '../../nodes'; +import type NodeManager from '../../nodes/NodeManager'; import type { NodeId } from '../../nodes/types'; -import type { Sigchain } from '../../sigchain'; -import type { KeyManager } from '../../keys'; +import type Sigchain from '../../sigchain/Sigchain'; +import type KeyManager from '../../keys/KeyManager'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { utils as claimsUtils, errors as claimsErrors } from '../../claims'; -import { utils as nodesUtils } from '../../nodes'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import * as claimsUtils from '../../claims/utils'; +import * as claimsErrors from '../../claims/errors'; +import * as nodesUtils from '../../nodes/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; function nodesCrossSignClaim({ + db, keyManager, nodeManager, sigchain, + logger, }: { + db: DB; keyManager: KeyManager; nodeManager: NodeManager; sigchain: Sigchain; + logger: Logger; }) { return async ( call: grpc.ServerDuplexStream, ) => { - // TODO: Move all "await genClaims.throw" to a final catch(). Wrap this - // entire thing in a try block. And re-throw whatever error is caught - const genClaims = grpcUtils.generatorDuplex(call); + const nodeId = keyManager.getNodeId(); + const genClaims = grpcUtils.generatorDuplex(call, { nodeId }, true); try { - await sigchain.transaction(async (sigchain) => { + await db.withTransactionF(async (tran) => { const readStatus = await genClaims.read(); // If nothing to read, end and destroy if (readStatus.done) { @@ -42,7 +49,6 @@ function nodesCrossSignClaim({ if (!intermediarySignature) { throw new claimsErrors.ErrorUndefinedSignature(); } - // 3. X --> responds with double signing the Y signed claim, and also --> Y // bundles it with its own signed claim (intermediate) // Reconstruct the claim to verify its signature @@ -99,11 +105,14 @@ function nodesCrossSignClaim({ signeeNodeId: nodesUtils.encodeNodeId(keyManager.getNodeId()), }); // Then create your own intermediary node claim (from X -> Y) - const singlySignedClaim = await sigchain.createIntermediaryClaim({ - type: 'node', - node1: nodesUtils.encodeNodeId(keyManager.getNodeId()), - node2: payloadData.node1, - }); + const singlySignedClaim = await sigchain.createIntermediaryClaim( + { + type: 'node', + node1: nodesUtils.encodeNodeId(keyManager.getNodeId()), + node2: payloadData.node1, + }, + tran, + ); // Should never be reached, but just for type safety if (!doublySignedClaim.payload || !singlySignedClaim.payload) { throw new claimsErrors.ErrorClaimsUndefinedClaimPayload(); @@ -149,20 +158,17 @@ function nodesCrossSignClaim({ senderPublicKey, )); if (!verifiedDoubly) { - await genClaims.throw( - new claimsErrors.ErrorDoublySignedClaimVerificationFailed(), - ); + throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed(); } // If verified, then we can safely add to our sigchain - await sigchain.addExistingClaim(constructedDoublySignedClaim); + await sigchain.addExistingClaim(constructedDoublySignedClaim, tran); // Close the stream await genClaims.next(null); return; }); } catch (e) { await genClaims.throw(e); - // TODO: Handle the exception on this server - throw e? - // throw e; + logger.error(e); return; } }; diff --git a/src/agent/service/nodesHolePunchMessageSend.ts b/src/agent/service/nodesHolePunchMessageSend.ts index d524e9f24..c1b681054 100644 --- a/src/agent/service/nodesHolePunchMessageSend.ts +++ b/src/agent/service/nodesHolePunchMessageSend.ts @@ -1,11 +1,15 @@ import type * as grpc from '@grpc/grpc-js'; -import type { NodeManager, NodeConnectionManager } from '../../nodes'; +import type { DB } from '@matrixai/db'; +import type NodeManager from '../../nodes/NodeManager'; +import type NodeConnectionManager from '../../nodes/NodeConnectionManager'; import type KeyManager from '../../keys/KeyManager'; import type { NodeId } from '../../nodes/types'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; +import type Logger from '@matrixai/logger'; import * as networkUtils from '../../network/utils'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; @@ -13,10 +17,14 @@ function nodesHolePunchMessageSend({ keyManager, nodeManager, nodeConnectionManager, + db, + logger, }: { keyManager: KeyManager; nodeManager: NodeManager; nodeConnectionManager: NodeConnectionManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -49,20 +57,23 @@ function nodesHolePunchMessageSend({ // Firstly, check if this node is the desired node // If so, then we want to make this node start sending hole punching packets // back to the source node. - if (keyManager.getNodeId().equals(targetId)) { - const [host, port] = networkUtils.parseAddress( - call.request.getProxyAddress(), - ); - await nodeConnectionManager.holePunchReverse(host, port); - // Otherwise, find if node in table - // If so, ask the nodeManager to relay to the node - } else if (await nodeManager.knowsNode(sourceId)) { - await nodeConnectionManager.relayHolePunchMessage(call.request); - } + await db.withTransactionF(async (tran) => { + if (keyManager.getNodeId().equals(targetId)) { + const [host, port] = networkUtils.parseAddress( + call.request.getProxyAddress(), + ); + await nodeConnectionManager.holePunchReverse(host, port); + // Otherwise, find if node in table + // If so, ask the nodeManager to relay to the node + } else if (await nodeManager.knowsNode(sourceId, tran)) { + await nodeConnectionManager.relayHolePunchMessage(call.request); + } + }); callback(null, response); return; } catch (e) { - callback(grpcUtils.fromError(e)); + callback(grpcUtils.fromError(e, true)); + logger.error(e); return; } }; diff --git a/src/agent/service/notificationsSend.ts b/src/agent/service/notificationsSend.ts index cf2b589ea..07aaf0933 100644 --- a/src/agent/service/notificationsSend.ts +++ b/src/agent/service/notificationsSend.ts @@ -1,14 +1,20 @@ import type * as grpc from '@grpc/grpc-js'; -import type { NotificationsManager } from '../../notifications'; +import type NotificationsManager from '../../notifications/NotificationsManager'; import type * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifications_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { utils as notificationsUtils } from '../../notifications'; +import type Logger from '@matrixai/logger'; +import type { DB } from '@matrixai/db'; +import * as grpcUtils from '../../grpc/utils'; +import * as notificationsUtils from '../../notifications/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function notificationsSend({ notificationsManager, + db, + logger, }: { notificationsManager: NotificationsManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall< @@ -18,14 +24,17 @@ function notificationsSend({ callback: grpc.sendUnaryData, ): Promise => { try { - const response = new utilsPB.EmptyMessage(); const jwt = call.request.getContent(); const notification = await notificationsUtils.verifyAndDecodeNotif(jwt); - await notificationsManager.receiveNotification(notification); + await db.withTransactionF(async (tran) => { + await notificationsManager.receiveNotification(notification, tran); + }); + const response = new utilsPB.EmptyMessage(); callback(null, response); return; } catch (e) { - callback(grpcUtils.fromError(e)); + callback(grpcUtils.fromError(e, true)); + logger.error(e); return; } }; diff --git a/src/agent/service/vaultsGitInfoGet.ts b/src/agent/service/vaultsGitInfoGet.ts index 72f01a74c..4a9893985 100644 --- a/src/agent/service/vaultsGitInfoGet.ts +++ b/src/agent/service/vaultsGitInfoGet.ts @@ -1,7 +1,9 @@ +import type { DB } from '@matrixai/db'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type ACL from '../../acl/ACL'; import type { ConnectionInfoGet } from '../../agent/types'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsUtils from '../../vaults/utils'; @@ -14,80 +16,91 @@ import * as agentErrors from '../errors'; function vaultsGitInfoGet({ vaultManager, acl, + db, + logger, connectionInfoGet, }: { vaultManager: VaultManager; acl: ACL; + db: DB; + logger: Logger; connectionInfoGet: ConnectionInfoGet; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); - const request = call.request; - const vaultMessage = request.getVault(); - if (vaultMessage == null) { - await genWritable.throw({ code: grpc.status.NOT_FOUND }); - return; - } - let vaultName; - const vaultNameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName); - vaultName = vaultNameOrId; - if (vaultId == null) { - try { - vaultId = validationUtils.parseVaultId(vaultNameOrId); - vaultName = (await vaultManager.getVaultMeta(vaultId))?.vaultName; - } catch (err) { - await genWritable.throw(new vaultsErrors.ErrorVaultsVaultUndefined()); - return; - } - } - // Getting the NodeId from the ReverseProxy connection info - const connectionInfo = connectionInfoGet(call); - // If this is getting run the connection exists - // It SHOULD exist here - if (connectionInfo == null) { - throw new agentErrors.ErrorConnectionInfoMissing(); - } - const nodeId = connectionInfo.remoteNodeId; - const nodeIdEncoded = nodesUtils.encodeNodeId(nodeId); - const actionType = validationUtils.parseVaultAction(request.getAction()); - const permissions = await acl.getNodePerm(nodeId); - if (permissions == null) { - await genWritable.throw( - new vaultsErrors.ErrorVaultsPermissionDenied( - `No permissions found for ${nodeIdEncoded}`, - ), - ); - return; - } - const vaultPerms = permissions.vaults[vaultId]; - if (vaultPerms?.[actionType] !== null) { - await genWritable.throw( - new vaultsErrors.ErrorVaultsPermissionDenied( - `${nodeIdEncoded} does not have permission to ${actionType} from vault ${vaultsUtils.encodeVaultId( - vaultId, - )}`, - ), - ); - return; - } - const meta = new grpc.Metadata(); - meta.set('vaultName', vaultName); - meta.set('vaultId', vaultsUtils.encodeVaultId(vaultId)); - genWritable.stream.sendMetadata(meta); - const response = new vaultsPB.PackChunk(); - const responseGen = vaultManager.handleInfoRequest(vaultId); - for await (const byte of responseGen) { - if (byte !== null) { - response.setChunk(byte); - await genWritable.next(response); - } else { - await genWritable.next(null); + const genWritable = grpcUtils.generatorWritable(call, true); + try { + const request = call.request; + const vaultMessage = request.getVault(); + if (vaultMessage == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); } + let vaultName; + const vaultNameOrId = vaultMessage.getNameOrId(); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + vaultNameOrId as VaultName, + tran, + ); + vaultName = vaultNameOrId; + if (vaultId == null) { + try { + vaultId = validationUtils.parseVaultId(vaultNameOrId); + vaultName = (await vaultManager.getVaultMeta(vaultId, tran)) + ?.vaultName; + } catch (e) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(e.message, { + cause: e, + }); + } + } + // Getting the NodeId from the ReverseProxy connection info + const connectionInfo = connectionInfoGet(call); + // If this is getting run the connection exists + // It SHOULD exist here + if (connectionInfo == null) { + throw new agentErrors.ErrorConnectionInfoMissing(); + } + const nodeId = connectionInfo.remoteNodeId; + const nodeIdEncoded = nodesUtils.encodeNodeId(nodeId); + const actionType = validationUtils.parseVaultAction( + request.getAction(), + ); + const permissions = await acl.getNodePerm(nodeId, tran); + if (permissions == null) { + throw new vaultsErrors.ErrorVaultsPermissionDenied( + `No permissions found for ${nodeIdEncoded}`, + ); + } + const vaultPerms = permissions.vaults[vaultId]; + if (vaultPerms?.[actionType] !== null) { + throw new vaultsErrors.ErrorVaultsPermissionDenied( + `${nodeIdEncoded} does not have permission to ${actionType} from vault ${vaultsUtils.encodeVaultId( + vaultId, + )}`, + ); + } + const meta = new grpc.Metadata(); + meta.set('vaultName', vaultName); + meta.set('vaultId', vaultsUtils.encodeVaultId(vaultId)); + genWritable.stream.sendMetadata(meta); + const response = new vaultsPB.PackChunk(); + const responseGen = vaultManager.handleInfoRequest(vaultId, tran); + for await (const byte of responseGen) { + if (byte !== null) { + response.setChunk(byte); + await genWritable.next(response); + } else { + await genWritable.next(null); + } + } + }); + await genWritable.next(null); + } catch (e) { + await genWritable.throw(e); + logger.error(e); } - await genWritable.next(null); }; } diff --git a/src/agent/service/vaultsGitPackGet.ts b/src/agent/service/vaultsGitPackGet.ts index 5528ade31..8d9561512 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -1,8 +1,11 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type { ConnectionInfoGet } from '../../agent/types'; import type ACL from '../../acl/ACL'; +import type KeyManager from '../../keys/KeyManager'; +import type Logger from '@matrixai/logger'; import * as nodesUtils from '../../nodes/utils'; import * as grpcErrors from '../../grpc/errors'; import * as grpcUtils from '../../grpc/utils'; @@ -15,86 +18,98 @@ import * as agentErrors from '../errors'; function vaultsGitPackGet({ vaultManager, acl, + db, + keyManager, + logger, connectionInfoGet, }: { vaultManager: VaultManager; acl: ACL; + db: DB; + keyManager: KeyManager; + logger: Logger; connectionInfoGet: ConnectionInfoGet; }) { return async ( call: grpc.ServerDuplexStream, - ) => { - const genDuplex = grpcUtils.generatorDuplex(call); - const clientBodyBuffers: Uint8Array[] = []; - const clientRequest = (await genDuplex.read()).value; - clientBodyBuffers.push(clientRequest!.getChunk_asU8()); - const body = Buffer.concat(clientBodyBuffers); - const meta = call.metadata; - // Getting the NodeId from the ReverseProxy connection info - const connectionInfo = connectionInfoGet(call); - // If this is getting run the connection exists - // It SHOULD exist here - if (connectionInfo == null) { - throw new agentErrors.ErrorConnectionInfoMissing(); - } - const nodeId = connectionInfo.remoteNodeId; - const nodeIdEncoded = nodesUtils.encodeNodeId(nodeId); - // Getting vaultId - const vaultNameOrId = meta.get('vaultNameOrId').pop()!.toString(); - if (vaultNameOrId == null) { - throw new grpcErrors.ErrorGRPC('vault-name not in metadata'); - } - let vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName); - vaultId = vaultId ?? vaultsUtils.decodeVaultId(vaultNameOrId); - if (vaultId == null) { - await genDuplex.throw( - // Throwing permission error to hide information about vaults existence - new vaultsErrors.ErrorVaultsPermissionDenied( - `No permissions found for ${nodeIdEncoded}`, - ), - ); - return; - } - // Checking permissions - const permissions = await acl.getNodePerm(nodeId); - const vaultPerms = permissions?.vaults[vaultId]; - const actionType = validationUtils.parseVaultAction( - meta.get('vaultAction').pop(), - ); - if (vaultPerms?.[actionType] !== null) { - await genDuplex.throw( - new vaultsErrors.ErrorVaultsPermissionDenied( - `${nodeIdEncoded} does not have permission to ${actionType} from vault ${vaultsUtils.encodeVaultId( - vaultId, - )}`, - ), - ); - return; - } - const response = new vaultsPB.PackChunk(); - const [sideBand, progressStream] = await vaultManager.handlePackRequest( - vaultId, - Buffer.from(body), - ); - response.setChunk(Buffer.from('0008NAK\n')); - await genDuplex.write(response); - const responseBuffers: Uint8Array[] = []; - await new Promise((resolve, reject) => { - sideBand.on('data', async (data: Uint8Array) => { - responseBuffers.push(data); - }); - sideBand.on('end', async () => { - response.setChunk(Buffer.concat(responseBuffers)); + ): Promise => { + const nodeId = keyManager.getNodeId(); + const genDuplex = grpcUtils.generatorDuplex(call, { nodeId }, true); + try { + const clientBodyBuffers: Uint8Array[] = []; + const clientRequest = (await genDuplex.read()).value; + clientBodyBuffers.push(clientRequest!.getChunk_asU8()); + const body = Buffer.concat(clientBodyBuffers); + const meta = call.metadata; + // Getting the NodeId from the ReverseProxy connection info + const connectionInfo = connectionInfoGet(call); + // If this is getting run the connection exists + // It SHOULD exist here + if (connectionInfo == null) { + throw new agentErrors.ErrorConnectionInfoMissing(); + } + const nodeId = connectionInfo.remoteNodeId; + const nodeIdEncoded = nodesUtils.encodeNodeId(nodeId); + // Getting vaultId + const vaultNameOrId = meta.get('vaultNameOrId').pop()!.toString(); + if (vaultNameOrId == null) { + throw new grpcErrors.ErrorGRPC('vault-name not in metadata'); + } + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + vaultNameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? vaultsUtils.decodeVaultId(vaultNameOrId); + if (vaultId == null) { + // Throwing permission error to hide information about vaults existence + throw new vaultsErrors.ErrorVaultsPermissionDenied( + `No permissions found for ${nodeIdEncoded}`, + ); + } + // Checking permissions + const permissions = await acl.getNodePerm(nodeId, tran); + const vaultPerms = permissions?.vaults[vaultId]; + const actionType = validationUtils.parseVaultAction( + meta.get('vaultAction').pop(), + ); + if (vaultPerms?.[actionType] !== null) { + throw new vaultsErrors.ErrorVaultsPermissionDenied( + `${nodeIdEncoded} does not have permission to ${actionType} from vault ${vaultsUtils.encodeVaultId( + vaultId, + )}`, + ); + } + const response = new vaultsPB.PackChunk(); + const [sideBand, progressStream] = await vaultManager.handlePackRequest( + vaultId, + Buffer.from(body), + tran, + ); + response.setChunk(Buffer.from('0008NAK\n')); await genDuplex.write(response); - resolve(); - }); - sideBand.on('error', (err) => { - reject(err); + const responseBuffers: Uint8Array[] = []; + await new Promise((resolve, reject) => { + sideBand.on('data', async (data: Uint8Array) => { + responseBuffers.push(data); + }); + sideBand.on('end', async () => { + response.setChunk(Buffer.concat(responseBuffers)); + await genDuplex.write(response); + resolve(); + }); + sideBand.on('error', (err) => { + reject(err); + }); + progressStream.write(Buffer.from('0014progress is at 50%\n')); + progressStream.end(); + }); }); - progressStream.write(Buffer.from('0014progress is at 50%\n')); - progressStream.end(); - }); - await genDuplex.next(null); + await genDuplex.next(null); + } catch (e) { + await genDuplex.throw(e); + logger.error(e); + } }; } diff --git a/src/agent/service/vaultsScan.ts b/src/agent/service/vaultsScan.ts index 6dfd028e4..2fd04d5e5 100644 --- a/src/agent/service/vaultsScan.ts +++ b/src/agent/service/vaultsScan.ts @@ -1,7 +1,9 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type VaultManager from '../../vaults/VaultManager'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; import type { ConnectionInfoGet } from '../../agent/types'; +import type Logger from '@matrixai/logger'; import * as agentErrors from '../../agent/errors'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; import * as vaultsUtils from '../../vaults/utils'; @@ -9,15 +11,19 @@ import * as grpcUtils from '../../grpc/utils'; function vaultsScan({ vaultManager, + logger, connectionInfoGet, + db, }: { vaultManager: VaultManager; + logger: Logger; connectionInfoGet: ConnectionInfoGet; + db: DB; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, true); const listMessage = new vaultsPB.List(); // Getting the NodeId from the ReverseProxy connection info const connectionInfo = connectionInfoGet(call); @@ -28,20 +34,23 @@ function vaultsScan({ } const nodeId = connectionInfo.remoteNodeId; try { - const listResponse = vaultManager.handleScanVaults(nodeId); - for await (const { - vaultId, - vaultName, - vaultPermissions, - } of listResponse) { - listMessage.setVaultId(vaultsUtils.encodeVaultId(vaultId)); - listMessage.setVaultName(vaultName); - listMessage.setVaultPermissionsList(vaultPermissions); - await genWritable.next(listMessage); - } + await db.withTransactionF(async (tran) => { + const listResponse = vaultManager.handleScanVaults(nodeId, tran); + for await (const { + vaultId, + vaultName, + vaultPermissions, + } of listResponse) { + listMessage.setVaultId(vaultsUtils.encodeVaultId(vaultId)); + listMessage.setVaultName(vaultName); + listMessage.setVaultPermissionsList(vaultPermissions); + await genWritable.next(listMessage); + } + }); await genWritable.next(null); } catch (e) { await genWritable.throw(e); + logger.error(e); } }; } diff --git a/src/bin/CommandPolykey.ts b/src/bin/CommandPolykey.ts index b9534fee0..9dd84a95f 100644 --- a/src/bin/CommandPolykey.ts +++ b/src/bin/CommandPolykey.ts @@ -70,7 +70,14 @@ class CommandPolykey extends commander.Command { if (opts.nodePath == null) { throw new binErrors.ErrorCLINodePath(); } - await fn(...args); + try { + await fn(...args); + } catch (e) { + const [errorCause, remoteLevel] = binUtils.remoteErrorCause(e); + console.log(remoteLevel); + console.error(errorCause); + throw errorCause; + } }); } } diff --git a/src/bin/agent/CommandStart.ts b/src/bin/agent/CommandStart.ts index d99a60369..e4b863a47 100644 --- a/src/bin/agent/CommandStart.ts +++ b/src/bin/agent/CommandStart.ts @@ -175,8 +175,10 @@ class CommandStart extends CommandPolykey { new binErrors.ErrorCLIPolykeyAgentProcess( 'Agent process closed during fork', { - code, - signal, + data: { + code, + signal, + }, }, ), ); diff --git a/src/bin/errors.ts b/src/bin/errors.ts index e8fa532a4..95951d260 100644 --- a/src/bin/errors.ts +++ b/src/bin/errors.ts @@ -1,56 +1,56 @@ import ErrorPolykey from '../ErrorPolykey'; import sysexits from '../utils/sysexits'; -class ErrorCLI extends ErrorPolykey {} +class ErrorCLI extends ErrorPolykey {} -class ErrorCLINodePath extends ErrorCLI { - description = 'Cannot derive default node path from unknown platform'; +class ErrorCLINodePath extends ErrorCLI { + static description = 'Cannot derive default node path from unknown platform'; exitCode = sysexits.USAGE; } -class ErrorCLIClientOptions extends ErrorCLI { - description = 'Missing required client options'; +class ErrorCLIClientOptions extends ErrorCLI { + static description = 'Missing required client options'; exitCode = sysexits.USAGE; } -class ErrorCLIPasswordMissing extends ErrorCLI { - description = +class ErrorCLIPasswordMissing extends ErrorCLI { + static description = 'Password is necessary, provide it via --password-file, PK_PASSWORD or when prompted'; exitCode = sysexits.USAGE; } -class ErrorCLIPasswordFileRead extends ErrorCLI { - description = 'Failed to read password file'; +class ErrorCLIPasswordFileRead extends ErrorCLI { + static description = 'Failed to read password file'; exitCode = sysexits.NOINPUT; } -class ErrorCLIRecoveryCodeFileRead extends ErrorCLI { - description = 'Failed to read recovery code file'; +class ErrorCLIRecoveryCodeFileRead extends ErrorCLI { + static description = 'Failed to read recovery code file'; exitCode = sysexits.NOINPUT; } -class ErrorCLIFileRead extends ErrorCLI { - description = 'Failed to read file'; +class ErrorCLIFileRead extends ErrorCLI { + static description = 'Failed to read file'; exitCode = sysexits.NOINPUT; } -class ErrorCLIPolykeyAgentStatus extends ErrorCLI { - description = 'PolykeyAgent agent status'; +class ErrorCLIPolykeyAgentStatus extends ErrorCLI { + static description = 'PolykeyAgent agent status'; exitCode = sysexits.TEMPFAIL; } -class ErrorCLIPolykeyAgentProcess extends ErrorCLI { - description = 'PolykeyAgent process could not be started'; +class ErrorCLIPolykeyAgentProcess extends ErrorCLI { + static description = 'PolykeyAgent process could not be started'; exitCode = sysexits.OSERR; } -class ErrorNodeFindFailed extends ErrorCLI { - description = 'Failed to find the node in the DHT'; +class ErrorNodeFindFailed extends ErrorCLI { + static description = 'Failed to find the node in the DHT'; exitCode = 1; } -class ErrorNodePingFailed extends ErrorCLI { - description = 'Node was not online or not found.'; +class ErrorNodePingFailed extends ErrorCLI { + static description = 'Node was not online or not found.'; exitCode = 1; } diff --git a/src/bin/keys/CommandDecrypt.ts b/src/bin/keys/CommandDecrypt.ts index 137757bbb..aeb4a5191 100644 --- a/src/bin/keys/CommandDecrypt.ts +++ b/src/bin/keys/CommandDecrypt.ts @@ -52,10 +52,13 @@ class CommandDecrypt extends CommandPolykey { }); } catch (e) { throw new binErrors.ErrorCLIFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } cryptoMessage.setData(cipherText); diff --git a/src/bin/keys/CommandEncrypt.ts b/src/bin/keys/CommandEncrypt.ts index dac9d52eb..2edef5b08 100644 --- a/src/bin/keys/CommandEncrypt.ts +++ b/src/bin/keys/CommandEncrypt.ts @@ -52,10 +52,13 @@ class CommandEncypt extends CommandPolykey { }); } catch (e) { throw new binErrors.ErrorCLIFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } cryptoMessage.setData(plainText); diff --git a/src/bin/keys/CommandSign.ts b/src/bin/keys/CommandSign.ts index 4d94d2a24..4d31dee5f 100644 --- a/src/bin/keys/CommandSign.ts +++ b/src/bin/keys/CommandSign.ts @@ -52,10 +52,13 @@ class CommandSign extends CommandPolykey { }); } catch (e) { throw new binErrors.ErrorCLIFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } cryptoMessage.setData(data); diff --git a/src/bin/keys/CommandVerify.ts b/src/bin/keys/CommandVerify.ts index 42dabed70..7c0a5de49 100644 --- a/src/bin/keys/CommandVerify.ts +++ b/src/bin/keys/CommandVerify.ts @@ -60,10 +60,13 @@ class CommandVerify extends CommandPolykey { }); } catch (e) { throw new binErrors.ErrorCLIFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } cryptoMessage.setData(data); diff --git a/src/bin/nodes/CommandFind.ts b/src/bin/nodes/CommandFind.ts index 5788c2c8a..32169a968 100644 --- a/src/bin/nodes/CommandFind.ts +++ b/src/bin/nodes/CommandFind.ts @@ -71,7 +71,9 @@ class CommandFind extends CommandPolykey { result.port as Port, )}`; } catch (err) { - if (!(err instanceof nodesErrors.ErrorNodeGraphNodeIdNotFound)) { + if ( + !(err.cause instanceof nodesErrors.ErrorNodeGraphNodeIdNotFound) + ) { throw err; } // Else failed to find the node. diff --git a/src/bin/nodes/CommandPing.ts b/src/bin/nodes/CommandPing.ts index b22e0d19d..a15779c55 100644 --- a/src/bin/nodes/CommandPing.ts +++ b/src/bin/nodes/CommandPing.ts @@ -55,11 +55,12 @@ class CommandPing extends CommandPolykey { meta, ); } catch (err) { - if (err instanceof nodesErrors.ErrorNodeGraphNodeIdNotFound) { + if (err.cause instanceof nodesErrors.ErrorNodeGraphNodeIdNotFound) { error = new binErrors.ErrorNodePingFailed( `Failed to resolve node ID ${nodesUtils.encodeNodeId( nodeId, )} to an address.`, + { cause: err }, ); } else { throw err; diff --git a/src/bin/polykey-agent.ts b/src/bin/polykey-agent.ts index d92dce2d5..d56d49220 100644 --- a/src/bin/polykey-agent.ts +++ b/src/bin/polykey-agent.ts @@ -40,7 +40,7 @@ async function main(_argv = process.argv): Promise { const processSend = promisify(process.send!.bind(process)); const { p: messageInP, resolveP: resolveMessageInP } = promise(); - process.once('message', (data) => { + process.once('message', (data: AgentChildProcessInput) => { resolveMessageInP(data); }); const messageIn = await messageInP; diff --git a/src/bin/secrets/CommandCreate.ts b/src/bin/secrets/CommandCreate.ts index b0d9a7d0d..26f22cbbe 100644 --- a/src/bin/secrets/CommandCreate.ts +++ b/src/bin/secrets/CommandCreate.ts @@ -65,10 +65,13 @@ class CommandCreate extends CommandPolykey { content = await this.fs.promises.readFile(directoryPath); } catch (e) { throw new binErrors.ErrorCLIFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } secretMessage.setSecretContent(content); diff --git a/src/bin/secrets/CommandEdit.ts b/src/bin/secrets/CommandEdit.ts index f3d005810..f86b37499 100644 --- a/src/bin/secrets/CommandEdit.ts +++ b/src/bin/secrets/CommandEdit.ts @@ -74,10 +74,13 @@ class CommandEdit extends CommandPolykey { content = await this.fs.promises.readFile(tmpFile); } catch (e) { throw new binErrors.ErrorCLIFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } secretMessage.setVault(vaultMessage); diff --git a/src/bin/secrets/CommandUpdate.ts b/src/bin/secrets/CommandUpdate.ts index 941006aed..c7b9e696d 100644 --- a/src/bin/secrets/CommandUpdate.ts +++ b/src/bin/secrets/CommandUpdate.ts @@ -65,10 +65,13 @@ class CommandUpdate extends CommandPolykey { content = await this.fs.promises.readFile(directoryPath); } catch (e) { throw new binErrors.ErrorCLIFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } secretMessage.setSecretContent(content); diff --git a/src/bin/utils/processors.ts b/src/bin/utils/processors.ts index 509134fc0..df43437d0 100644 --- a/src/bin/utils/processors.ts +++ b/src/bin/utils/processors.ts @@ -89,10 +89,13 @@ async function processPassword( password = (await fs.promises.readFile(passwordFile, 'utf-8')).trim(); } catch (e) { throw new binErrors.ErrorCLIPasswordFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } else if (typeof process.env['PK_PASSWORD'] === 'string') { @@ -131,10 +134,13 @@ async function processNewPassword( ).trim(); } catch (e) { throw new binErrors.ErrorCLIPasswordFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } else if (!existing && typeof process.env['PK_PASSWORD'] === 'string') { @@ -167,10 +173,13 @@ async function processRecoveryCode( ).trim(); } catch (e) { throw new binErrors.ErrorCLIRecoveryCodeFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } else if (typeof process.env['PK_RECOVERY_CODE'] === 'string') { @@ -372,10 +381,13 @@ async function processAuthentication( password = (await fs.promises.readFile(passwordFile, 'utf-8')).trim(); } catch (e) { throw new binErrors.ErrorCLIPasswordFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } meta = clientUtils.encodeAuthFromPassword(password); diff --git a/src/bin/utils/utils.ts b/src/bin/utils/utils.ts index c902337e8..5477228a9 100644 --- a/src/bin/utils/utils.ts +++ b/src/bin/utils/utils.ts @@ -6,6 +6,7 @@ import * as binProcessors from './processors'; import * as binErrors from '../errors'; import * as clientUtils from '../../client/utils'; import * as clientErrors from '../../client/errors'; +import * as errors from '../../errors'; /** * Convert verbosity to LogLevel @@ -122,9 +123,10 @@ async function retryAuthentication( throw e; } // If it is exception is not missing or denied, then throw the exception + const [cause] = remoteErrorCause(e); if ( - !(e instanceof clientErrors.ErrorClientAuthMissing) && - !(e instanceof clientErrors.ErrorClientAuthDenied) + !(cause instanceof clientErrors.ErrorClientAuthMissing) && + !(cause instanceof clientErrors.ErrorClientAuthDenied) ) { throw e; } @@ -141,14 +143,30 @@ async function retryAuthentication( try { return await f(meta); } catch (e) { + const [cause] = remoteErrorCause(e); // The auth cannot be missing, so when it is denied do we retry - if (!(e instanceof clientErrors.ErrorClientAuthDenied)) { + if (!(cause instanceof clientErrors.ErrorClientAuthDenied)) { throw e; } } } } -export { verboseToLogLevel, outputFormatter, retryAuthentication }; +function remoteErrorCause(e: any): [any, number] { + let errorCause = e; + let depth = 0; + while (e instanceof errors.ErrorPolykeyRemote) { + errorCause = e.cause; + depth++; + } + return [errorCause, depth]; +} + +export { + verboseToLogLevel, + outputFormatter, + retryAuthentication, + remoteErrorCause, +}; export type { OutputObject }; diff --git a/src/bootstrap/errors.ts b/src/bootstrap/errors.ts index 1e24566a2..c2e25289c 100644 --- a/src/bootstrap/errors.ts +++ b/src/bootstrap/errors.ts @@ -1,9 +1,9 @@ import { ErrorPolykey, sysexits } from '../errors'; -class ErrorBootstrap extends ErrorPolykey {} +class ErrorBootstrap extends ErrorPolykey {} -class ErrorBootstrapExistingState extends ErrorBootstrap { - description = 'Node path is occupied with existing state'; +class ErrorBootstrapExistingState extends ErrorBootstrap { + static description = 'Node path is occupied with existing state'; exitCode = sysexits.USAGE; } diff --git a/src/claims/errors.ts b/src/claims/errors.ts index 769911597..95b03c74a 100644 --- a/src/claims/errors.ts +++ b/src/claims/errors.ts @@ -1,54 +1,99 @@ -import { ErrorPolykey } from '../errors'; +import { ErrorPolykey, sysexits } from '../errors'; -class ErrorClaims extends ErrorPolykey {} +class ErrorClaims extends ErrorPolykey {} -class ErrorClaimsUndefinedCanonicalizedClaim extends ErrorClaims {} +class ErrorClaimsUndefinedCanonicalizedClaim extends ErrorClaims { + static description = 'Could not canonicalize claim'; + exitCode = sysexits.UNKNOWN; +} -class ErrorClaimsUndefinedClaimPayload extends ErrorClaims {} +class ErrorClaimsUndefinedClaimPayload extends ErrorClaims { + static description = 'Missing claim payload'; + exitCode = sysexits.UNKNOWN; +} -class ErrorClaimsUndefinedSignatureHeader extends ErrorClaims {} +class ErrorClaimsUndefinedSignatureHeader extends ErrorClaims { + static description = 'Missing signature header'; + exitCode = sysexits.UNKNOWN; +} /** * Exceptions arising in cross-signing process (GRPC) */ -class ErrorCrossSign extends ErrorClaims {} +class ErrorCrossSign extends ErrorClaims {} -class ErrorEmptyStream extends ErrorCrossSign {} +class ErrorEmptyStream extends ErrorCrossSign { + static description = 'Unexpected end of stream'; + exitCode = sysexits.IOERR; +} -class ErrorUndefinedSinglySignedClaim extends ErrorCrossSign { - description: string = 'An expected singly signed claim was not received'; +class ErrorUndefinedSinglySignedClaim extends ErrorCrossSign { + static description: string = + 'An expected singly signed claim was not received'; + exitCode = sysexits.USAGE; } -class ErrorUndefinedDoublySignedClaim extends ErrorCrossSign { - description: string = 'An expected doubly signed claim was not received'; +class ErrorUndefinedDoublySignedClaim extends ErrorCrossSign { + static description: string = + 'An expected doubly signed claim was not received'; + exitCode = sysexits.USAGE; } -class ErrorUndefinedSignature extends ErrorCrossSign { - description: string = 'A received claim does not have an expected signature'; +class ErrorUndefinedSignature extends ErrorCrossSign { + static description: string = + 'A received claim does not have an expected signature'; + exitCode = sysexits.CONFIG; } -class ErrorSinglySignedClaimVerificationFailed extends ErrorCrossSign {} +class ErrorSinglySignedClaimVerificationFailed extends ErrorCrossSign { + static description = 'Unable to verify intermediary claim'; + exitCode = sysexits.CONFIG; +} -class ErrorDoublySignedClaimVerificationFailed extends ErrorCrossSign {} +class ErrorDoublySignedClaimVerificationFailed extends ErrorCrossSign { + static description = 'Unable to verify claim'; + exitCode = sysexits.CONFIG; +} /** * Exceptions arising during schema validation */ -class ErrorSchemaValidate extends ErrorClaims {} +class ErrorSchemaValidate extends ErrorClaims {} -class ErrorClaimValidationFailed extends ErrorSchemaValidate {} +class ErrorClaimValidationFailed extends ErrorSchemaValidate { + static description = 'Claim data does not match schema'; + exitCode = sysexits.CONFIG; +} -class ErrorNodesClaimType extends ErrorSchemaValidate {} +class ErrorNodesClaimType extends ErrorSchemaValidate { + static description = 'Invalid claim type'; + exitCode = sysexits.CONFIG; +} -class ErrorIdentitiesClaimType extends ErrorSchemaValidate {} +class ErrorIdentitiesClaimType extends ErrorSchemaValidate { + static description = 'Invalid claim type'; + exitCode = sysexits.CONFIG; +} -class ErrorSinglySignedClaimNumSignatures extends ErrorSchemaValidate {} +class ErrorSinglySignedClaimNumSignatures extends ErrorSchemaValidate { + static description = 'Claim is not signed or has more than one signature'; + exitCode = sysexits.CONFIG; +} -class ErrorDoublySignedClaimNumSignatures extends ErrorSchemaValidate {} +class ErrorDoublySignedClaimNumSignatures extends ErrorSchemaValidate { + static description = 'Claim is not signed or does not have two signatures'; + exitCode = sysexits.CONFIG; +} -class ErrorSinglySignedClaimValidationFailed extends ErrorSchemaValidate {} +class ErrorSinglySignedClaimValidationFailed extends ErrorSchemaValidate { + static description = 'Claim data does not match schema'; + exitCode = sysexits.CONFIG; +} -class ErrorDoublySignedClaimValidationFailed extends ErrorSchemaValidate {} +class ErrorDoublySignedClaimValidationFailed extends ErrorSchemaValidate { + static description = 'Claim data does not match schema'; + exitCode = sysexits.CONFIG; +} export { ErrorClaims, diff --git a/src/client/GRPCClientClient.ts b/src/client/GRPCClientClient.ts index 3b07305ea..e866ec475 100644 --- a/src/client/GRPCClientClient.ts +++ b/src/client/GRPCClientClient.ts @@ -91,6 +91,11 @@ class GRPCClientClient extends GRPCClient { public agentStatus(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.agentStatus, )(...args); } @@ -99,6 +104,11 @@ class GRPCClientClient extends GRPCClient { public agentStop(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.agentStop, )(...args); } @@ -107,6 +117,11 @@ class GRPCClientClient extends GRPCClient { public agentUnlock(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.agentUnlock, )(...args); } @@ -115,6 +130,11 @@ class GRPCClientClient extends GRPCClient { public agentLockAll(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.agentLockAll, )(...args); } @@ -128,6 +148,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsList, )(...args); } @@ -136,6 +161,11 @@ class GRPCClientClient extends GRPCClient { public vaultsCreate(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsCreate, )(...args); } @@ -144,6 +174,11 @@ class GRPCClientClient extends GRPCClient { public vaultsRename(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsRename, )(...args); } @@ -152,6 +187,11 @@ class GRPCClientClient extends GRPCClient { public vaultsDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsDelete, )(...args); } @@ -160,6 +200,11 @@ class GRPCClientClient extends GRPCClient { public vaultsClone(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsClone, )(...args); } @@ -168,6 +213,11 @@ class GRPCClientClient extends GRPCClient { public vaultsPull(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsPull, )(...args); } @@ -181,6 +231,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsScan, )(...args); } @@ -189,6 +244,11 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsPermissionGet, )(...args); } @@ -197,6 +257,11 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionSet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsPermissionSet, )(...args); } @@ -205,6 +270,11 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionUnset(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsPermissionUnset, )(...args); } @@ -218,6 +288,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsList, )(...args); } @@ -226,6 +301,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsMkdir(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsMkdir, )(...args); } @@ -234,6 +314,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsDelete, )(...args); } @@ -242,6 +327,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsEdit(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsEdit, )(...args); } @@ -250,6 +340,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsGet, )(...args); } @@ -258,6 +353,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsStat(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsStat, )(...args); } @@ -266,6 +366,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsRename(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsRename, )(...args); } @@ -274,6 +379,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsNew(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsNew, )(...args); } @@ -282,6 +392,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsNewDir(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsNewDir, )(...args); } @@ -290,6 +405,11 @@ class GRPCClientClient extends GRPCClient { public vaultsVersion(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsVersion, )(...args); } @@ -303,6 +423,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsLog, )(...args); } @@ -311,6 +436,11 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairRoot(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysKeyPairRoot, )(...args); } @@ -319,6 +449,11 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairReset(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysKeyPairReset, )(...args); } @@ -327,6 +462,11 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairRenew(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysKeyPairRenew, )(...args); } @@ -335,6 +475,11 @@ class GRPCClientClient extends GRPCClient { public keysEncrypt(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysEncrypt, )(...args); } @@ -343,6 +488,11 @@ class GRPCClientClient extends GRPCClient { public keysDecrypt(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysDecrypt, )(...args); } @@ -351,6 +501,11 @@ class GRPCClientClient extends GRPCClient { public keysSign(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysSign, )(...args); } @@ -359,6 +514,11 @@ class GRPCClientClient extends GRPCClient { public keysVerify(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysVerify, )(...args); } @@ -367,6 +527,11 @@ class GRPCClientClient extends GRPCClient { public keysPasswordChange(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysPasswordChange, )(...args); } @@ -375,6 +540,11 @@ class GRPCClientClient extends GRPCClient { public keysCertsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysCertsGet, )(...args); } @@ -388,6 +558,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysCertsChainGet, )(...args); } @@ -401,6 +576,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltList, )(...args); } @@ -409,6 +589,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltGetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltGetByIdentity, )(...args); } @@ -417,6 +602,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltGetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltGetByNode, )(...args); } @@ -425,6 +615,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsDiscoveryByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsDiscoveryByNode, )(...args); } @@ -433,6 +628,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsDiscoveryByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsDiscoveryByIdentity, )(...args); } @@ -441,6 +641,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsGetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsGetByNode, )(...args); } @@ -449,6 +654,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsGetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsGetByIdentity, )(...args); } @@ -457,6 +667,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsSetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsSetByNode, )(...args); } @@ -465,6 +680,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsSetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsSetByIdentity, )(...args); } @@ -473,6 +693,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsUnsetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsUnsetByNode, )(...args); } @@ -481,6 +706,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsUnsetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsUnsetByIdentity, )(...args); } @@ -489,6 +719,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltTrustByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltTrustByNode, )(...args); } @@ -497,6 +732,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltTrustByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltTrustByIdentity, )(...args); } @@ -505,6 +745,11 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenPut(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesTokenPut, )(...args); } @@ -513,6 +758,11 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesTokenGet, )(...args); } @@ -521,6 +771,11 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesTokenDelete, )(...args); } @@ -529,6 +784,11 @@ class GRPCClientClient extends GRPCClient { public identitiesProvidersList(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesProvidersList, )(...args); } @@ -537,6 +797,11 @@ class GRPCClientClient extends GRPCClient { public nodesAdd(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesAdd, )(...args); } @@ -545,6 +810,11 @@ class GRPCClientClient extends GRPCClient { public nodesPing(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesPing, )(...args); } @@ -553,6 +823,11 @@ class GRPCClientClient extends GRPCClient { public nodesClaim(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesClaim, )(...args); } @@ -561,6 +836,11 @@ class GRPCClientClient extends GRPCClient { public nodesFind(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesFind, )(...args); } @@ -569,6 +849,11 @@ class GRPCClientClient extends GRPCClient { public identitiesAuthenticate(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesAuthenticate, )(...args); } @@ -577,6 +862,11 @@ class GRPCClientClient extends GRPCClient { public identitiesInfoConnectedGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesInfoConnectedGet, )(...args); } @@ -585,6 +875,11 @@ class GRPCClientClient extends GRPCClient { public identitiesInfoGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesInfoGet, )(...args); } @@ -593,6 +888,11 @@ class GRPCClientClient extends GRPCClient { public identitiesClaim(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesClaim, )(...args); } @@ -601,6 +901,11 @@ class GRPCClientClient extends GRPCClient { public identitiesAuthenticatedGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesAuthenticatedGet, )(...args); } @@ -609,6 +914,11 @@ class GRPCClientClient extends GRPCClient { public notificationsSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.notificationsSend, )(...args); } @@ -617,6 +927,11 @@ class GRPCClientClient extends GRPCClient { public notificationsRead(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.notificationsRead, )(...args); } @@ -625,6 +940,11 @@ class GRPCClientClient extends GRPCClient { public notificationsClear(...args) { return grpcUtils.promisifyUnaryCall( this.client, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.notificationsClear, )(...args); } diff --git a/src/client/errors.ts b/src/client/errors.ts index 246ddb084..13baa73b0 100644 --- a/src/client/errors.ts +++ b/src/client/errors.ts @@ -1,24 +1,24 @@ import { ErrorPolykey, sysexits } from '../errors'; -class ErrorClient extends ErrorPolykey {} +class ErrorClient extends ErrorPolykey {} -class ErrorClientClientDestroyed extends ErrorClient { - description = 'GRPCClientClient has been destroyed'; +class ErrorClientClientDestroyed extends ErrorClient { + static description = 'GRPCClientClient has been destroyed'; exitCode = sysexits.USAGE; } -class ErrorClientAuthMissing extends ErrorClient { - description = 'Authorisation metadata is required but missing'; +class ErrorClientAuthMissing extends ErrorClient { + static description = 'Authorisation metadata is required but missing'; exitCode = sysexits.NOPERM; } -class ErrorClientAuthFormat extends ErrorClient { - description = 'Authorisation metadata has invalid format'; +class ErrorClientAuthFormat extends ErrorClient { + static description = 'Authorisation metadata has invalid format'; exitCode = sysexits.USAGE; } -class ErrorClientAuthDenied extends ErrorClient { - description = 'Authorisation metadata is incorrect or expired'; +class ErrorClientAuthDenied extends ErrorClient { + static description = 'Authorisation metadata is incorrect or expired'; exitCode = sysexits.NOPERM; } diff --git a/src/client/service/agentLockAll.ts b/src/client/service/agentLockAll.ts index dd80ebf62..1bc011b08 100644 --- a/src/client/service/agentLockAll.ts +++ b/src/client/service/agentLockAll.ts @@ -1,15 +1,21 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { SessionManager } from '../../sessions'; +import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function agentLockAll({ - sessionManager, authenticate, + sessionManager, + db, + logger, }: { - sessionManager: SessionManager; authenticate: Authenticate; + sessionManager: SessionManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -19,11 +25,14 @@ function agentLockAll({ const response = new utilsPB.EmptyMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - await sessionManager.resetKey(); + await db.withTransactionF( + async (tran) => await sessionManager.resetKey(tran), + ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/agentStatus.ts b/src/client/service/agentStatus.ts index e90042ebd..ecac4e1c1 100644 --- a/src/client/service/agentStatus.ts +++ b/src/client/service/agentStatus.ts @@ -4,6 +4,7 @@ import type KeyManager from '../../keys/KeyManager'; import type GRPCServer from '../../grpc/GRPCServer'; import type Proxy from '../../network/Proxy'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import process from 'process'; import * as grpcUtils from '../../grpc/utils'; import * as nodesUtils from '../../nodes/utils'; @@ -15,12 +16,14 @@ function agentStatus({ grpcServerClient, grpcServerAgent, proxy, + logger, }: { authenticate: Authenticate; keyManager: KeyManager; grpcServerClient: GRPCServer; grpcServerAgent: GRPCServer; proxy: Proxy; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -46,6 +49,7 @@ function agentStatus({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/agentStop.ts b/src/client/service/agentStop.ts index 6f0c83bdc..f359036b8 100644 --- a/src/client/service/agentStop.ts +++ b/src/client/service/agentStop.ts @@ -1,6 +1,7 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type PolykeyAgent from '../../PolykeyAgent'; +import type Logger from '@matrixai/logger'; import { status, running } from '@matrixai/async-init'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; @@ -8,9 +9,11 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function agentStop({ authenticate, pkAgent, + logger, }: { authenticate: Authenticate; pkAgent: PolykeyAgent; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -29,6 +32,7 @@ function agentStop({ callback(null, response); } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } // Stop is called after GRPC resources are cleared diff --git a/src/client/service/agentUnlock.ts b/src/client/service/agentUnlock.ts index a3ff33ddd..1814eb81a 100644 --- a/src/client/service/agentUnlock.ts +++ b/src/client/service/agentUnlock.ts @@ -1,9 +1,16 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; +import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -function agentUnlock({ authenticate }: { authenticate: Authenticate }) { +function agentUnlock({ + authenticate, + logger, +}: { + authenticate: Authenticate; + logger: Logger; +}) { return async ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, @@ -16,6 +23,7 @@ function agentUnlock({ authenticate }: { authenticate: Authenticate }) { return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsGetByIdentity.ts b/src/client/service/gestaltsActionsGetByIdentity.ts index c4df02f2c..a1ee40c4a 100644 --- a/src/client/service/gestaltsActionsGetByIdentity.ts +++ b/src/client/service/gestaltsActionsGetByIdentity.ts @@ -1,19 +1,27 @@ +import type Logger from '@matrixai/logger'; import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { IdentityId, ProviderId } from '../../identities/types'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; -import { matchSync } from '../../utils'; +import { matchSync } from '../../utils/matchers'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; +import * as validationErrors from '../../validation/errors'; +import * as grpcUtils from '../../grpc/utils'; import * as permissionsPB from '../../proto/js/polykey/v1/permissions/permissions_pb'; function gestaltsActionsGetByIdentity({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -39,9 +47,9 @@ function gestaltsActionsGetByIdentity({ identityId: call.request.getIdentityId(), }, ); - const result = await gestaltGraph.getGestaltActionsByIdentity( - providerId, - identityId, + + const result = await db.withTransactionF(async (tran) => + gestaltGraph.getGestaltActionsByIdentity(providerId, identityId, tran), ); if (result == null) { // Node doesn't exist, so no permissions @@ -55,6 +63,9 @@ function gestaltsActionsGetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); + if (!(e instanceof validationErrors.ErrorValidation)) { + logger.error(e); + } return; } }; diff --git a/src/client/service/gestaltsActionsGetByNode.ts b/src/client/service/gestaltsActionsGetByNode.ts index f4bcd4d5a..77ad8360a 100644 --- a/src/client/service/gestaltsActionsGetByNode.ts +++ b/src/client/service/gestaltsActionsGetByNode.ts @@ -1,19 +1,26 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { NodeId } from '../../nodes/types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as permissionsPB from '../../proto/js/polykey/v1/permissions/permissions_pb'; function gestaltsActionsGetByNode({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -34,7 +41,9 @@ function gestaltsActionsGetByNode({ nodeId: call.request.getNodeId(), }, ); - const result = await gestaltGraph.getGestaltActionsByNode(nodeId); + const result = await db.withTransactionF(async (tran) => + gestaltGraph.getGestaltActionsByNode(nodeId, tran), + ); if (result == null) { // Node doesn't exist, so no permissions response.setActionList([]); @@ -47,6 +56,7 @@ function gestaltsActionsGetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsSetByIdentity.ts b/src/client/service/gestaltsActionsSetByIdentity.ts index 0a7637876..b0975d562 100644 --- a/src/client/service/gestaltsActionsSetByIdentity.ts +++ b/src/client/service/gestaltsActionsSetByIdentity.ts @@ -1,20 +1,27 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { GestaltAction } from '../../gestalts/types'; import type { IdentityId, ProviderId } from '../../identities/types'; import type * as permissionsPB from '../../proto/js/polykey/v1/permissions/permissions_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsActionsSetByIdentity({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -47,15 +54,19 @@ function gestaltsActionsSetByIdentity({ identityId: call.request.getIdentity()?.getIdentityId(), }, ); - await gestaltGraph.setGestaltActionByIdentity( - providerId, - identityId, - action, + await db.withTransactionF(async (tran) => + gestaltGraph.setGestaltActionByIdentity( + providerId, + identityId, + action, + tran, + ), ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsSetByNode.ts b/src/client/service/gestaltsActionsSetByNode.ts index f7e2e22fc..917e3b198 100644 --- a/src/client/service/gestaltsActionsSetByNode.ts +++ b/src/client/service/gestaltsActionsSetByNode.ts @@ -1,20 +1,27 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { GestaltAction } from '../../gestalts/types'; import type { NodeId } from '../../nodes/types'; import type * as permissionsPB from '../../proto/js/polykey/v1/permissions/permissions_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsActionsSetByNode({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -38,11 +45,14 @@ function gestaltsActionsSetByNode({ action: call.request.getAction(), }, ); - await gestaltGraph.setGestaltActionByNode(nodeId, action); + await db.withTransactionF(async (tran) => + gestaltGraph.setGestaltActionByNode(nodeId, action, tran), + ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsUnsetByIdentity.ts b/src/client/service/gestaltsActionsUnsetByIdentity.ts index a247babd8..cb976d117 100644 --- a/src/client/service/gestaltsActionsUnsetByIdentity.ts +++ b/src/client/service/gestaltsActionsUnsetByIdentity.ts @@ -1,20 +1,27 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { GestaltAction } from '../../gestalts/types'; import type { IdentityId, ProviderId } from '../../identities/types'; import type * as permissionsPB from '../../proto/js/polykey/v1/permissions/permissions_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsActionsUnsetByIdentity({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -47,15 +54,19 @@ function gestaltsActionsUnsetByIdentity({ identityId: call.request.getIdentity()?.getIdentityId(), }, ); - await gestaltGraph.unsetGestaltActionByIdentity( - providerId, - identityId, - action, + await db.withTransactionF(async (tran) => + gestaltGraph.unsetGestaltActionByIdentity( + providerId, + identityId, + action, + tran, + ), ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsUnsetByNode.ts b/src/client/service/gestaltsActionsUnsetByNode.ts index 0add07203..2bc5d410f 100644 --- a/src/client/service/gestaltsActionsUnsetByNode.ts +++ b/src/client/service/gestaltsActionsUnsetByNode.ts @@ -1,20 +1,27 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { GestaltAction } from '../../gestalts/types'; import type { NodeId } from '../../nodes/types'; import type * as permissionsPB from '../../proto/js/polykey/v1/permissions/permissions_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsActionsUnsetByNode({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -38,11 +45,14 @@ function gestaltsActionsUnsetByNode({ action: call.request.getAction(), }, ); - await gestaltGraph.unsetGestaltActionByNode(nodeId, action); + await db.withTransactionF(async (tran) => + gestaltGraph.unsetGestaltActionByNode(nodeId, action, tran), + ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsDiscoveryByIdentity.ts b/src/client/service/gestaltsDiscoveryByIdentity.ts index 4ebeae0ce..9834d4e7c 100644 --- a/src/client/service/gestaltsDiscoveryByIdentity.ts +++ b/src/client/service/gestaltsDiscoveryByIdentity.ts @@ -1,8 +1,9 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { Discovery } from '../../discovery'; +import type Discovery from '../../discovery/Discovery'; import type { IdentityId, ProviderId } from '../../identities/types'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; +import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; @@ -12,9 +13,11 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsDiscoveryByIdentity({ authenticate, discovery, + logger, }: { authenticate: Authenticate; discovery: Discovery; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -48,6 +51,7 @@ function gestaltsDiscoveryByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsDiscoveryByNode.ts b/src/client/service/gestaltsDiscoveryByNode.ts index c8f900141..ed8ab18e6 100644 --- a/src/client/service/gestaltsDiscoveryByNode.ts +++ b/src/client/service/gestaltsDiscoveryByNode.ts @@ -1,8 +1,9 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { Discovery } from '../../discovery'; +import type Discovery from '../../discovery/Discovery'; import type { NodeId } from '../../nodes/types'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; +import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; @@ -12,9 +13,11 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsDiscoveryByNode({ authenticate, discovery, + logger, }: { authenticate: Authenticate; discovery: Discovery; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -44,6 +47,7 @@ function gestaltsDiscoveryByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltGetByIdentity.ts b/src/client/service/gestaltsGestaltGetByIdentity.ts index 357761c11..4e4a25d78 100644 --- a/src/client/service/gestaltsGestaltGetByIdentity.ts +++ b/src/client/service/gestaltsGestaltGetByIdentity.ts @@ -1,19 +1,26 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { IdentityId, ProviderId } from '../../identities/types'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; function gestaltsGestaltGetByIdentity({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -42,9 +49,8 @@ function gestaltsGestaltGetByIdentity({ identityId: call.request.getIdentityId(), }, ); - const gestalt = await gestaltGraph.getGestaltByIdentity( - providerId, - identityId, + const gestalt = await db.withTransactionF(async (tran) => + gestaltGraph.getGestaltByIdentity(providerId, identityId, tran), ); if (gestalt != null) { response.setGestaltGraph(JSON.stringify(gestalt)); @@ -53,6 +59,7 @@ function gestaltsGestaltGetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltGetByNode.ts b/src/client/service/gestaltsGestaltGetByNode.ts index 424ad0f65..28fc02c3f 100644 --- a/src/client/service/gestaltsGestaltGetByNode.ts +++ b/src/client/service/gestaltsGestaltGetByNode.ts @@ -1,19 +1,26 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { NodeId } from '../../nodes/types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; function gestaltsGestaltGetByNode({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -38,7 +45,9 @@ function gestaltsGestaltGetByNode({ nodeId: call.request.getNodeId(), }, ); - const gestalt = await gestaltGraph.getGestaltByNode(nodeId); + const gestalt = await db.withTransactionF(async (tran) => + gestaltGraph.getGestaltByNode(nodeId, tran), + ); if (gestalt != null) { response.setGestaltGraph(JSON.stringify(gestalt)); } @@ -46,6 +55,7 @@ function gestaltsGestaltGetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltList.ts b/src/client/service/gestaltsGestaltList.ts index 458b5cf32..bb96dd53a 100644 --- a/src/client/service/gestaltsGestaltList.ts +++ b/src/client/service/gestaltsGestaltList.ts @@ -1,27 +1,35 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { Gestalt } from '../../gestalts/types'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; function gestaltsGestaltList({ authenticate, gestaltGraph, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); let gestaltMessage: gestaltsPB.Gestalt; try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const certs: Array = await gestaltGraph.getGestalts(); + const certs: Array = await db.withTransactionF(async (tran) => + gestaltGraph.getGestalts(tran), + ); for (const cert of certs) { gestaltMessage = new gestaltsPB.Gestalt(); gestaltMessage.setName(JSON.stringify(cert)); @@ -31,6 +39,7 @@ function gestaltsGestaltList({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltTrustByIdentity.ts b/src/client/service/gestaltsGestaltTrustByIdentity.ts index 754364f79..71368e7fb 100644 --- a/src/client/service/gestaltsGestaltTrustByIdentity.ts +++ b/src/client/service/gestaltsGestaltTrustByIdentity.ts @@ -1,9 +1,11 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { IdentityId, ProviderId } from '../../identities/types'; -import type { Discovery } from '../../discovery'; +import type Discovery from '../../discovery/Discovery'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; +import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; @@ -14,10 +16,14 @@ function gestaltsGestaltTrustByIdentity({ authenticate, gestaltGraph, discovery, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; discovery: Discovery; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -47,29 +53,36 @@ function gestaltsGestaltTrustByIdentity({ }, ); // Set the identity in the gestalt graph if not already - if ( - (await gestaltGraph.getGestaltByIdentity(providerId, identityId)) == - null - ) { - // Queue the new identity for discovery - // This will only add the identity to the GG if it is connected to a - // node (required to set permissions for it) - await discovery.queueDiscoveryByIdentity(providerId, identityId); - } - // We can currently only set permissions for identities that are - // connected to at least one node. If these conditions are not met, this - // will throw an error. Since discovery can take time, you may need to - // reattempt this command if it fails on the first attempt and you expect - // there to be a linked node for the identity. - await gestaltGraph.setGestaltActionByIdentity( - providerId, - identityId, - 'notify', - ); + await db.withTransactionF(async (tran) => { + if ( + (await gestaltGraph.getGestaltByIdentity( + providerId, + identityId, + tran, + )) == null + ) { + // Queue the new identity for discovery + // This will only add the identity to the GG if it is connected to a + // node (required to set permissions for it) + await discovery.queueDiscoveryByIdentity(providerId, identityId); + } + // We can currently only set permissions for identities that are + // connected to at least one node. If these conditions are not met, this + // will throw an error. Since discovery can take time, you may need to + // reattempt this command if it fails on the first attempt and you expect + // there to be a linked node for the identity. + await gestaltGraph.setGestaltActionByIdentity( + providerId, + identityId, + 'notify', + tran, + ); + }); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltTrustByNode.ts b/src/client/service/gestaltsGestaltTrustByNode.ts index b8f03fb87..097a94b07 100644 --- a/src/client/service/gestaltsGestaltTrustByNode.ts +++ b/src/client/service/gestaltsGestaltTrustByNode.ts @@ -1,9 +1,11 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { GestaltGraph } from '../../gestalts'; -import type { Discovery } from '../../discovery'; +import type GestaltGraph from '../../gestalts/GestaltGraph'; +import type Discovery from '../../discovery/Discovery'; import type { NodeId } from '../../nodes/types'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; +import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; @@ -15,10 +17,14 @@ function gestaltsGestaltTrustByNode({ authenticate, gestaltGraph, discovery, + db, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; discovery: Discovery; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -43,21 +49,27 @@ function gestaltsGestaltTrustByNode({ nodeId: call.request.getNodeId(), }, ); - // Set the node in the gestalt graph if not already - if ((await gestaltGraph.getGestaltByNode(nodeId)) == null) { - await gestaltGraph.setNode({ - id: nodesUtils.encodeNodeId(nodeId), - chain: {}, - }); - // Queue the new node for discovery - await discovery.queueDiscoveryByNode(nodeId); - } - // Set notify permission - await gestaltGraph.setGestaltActionByNode(nodeId, 'notify'); + await db.withTransactionF(async (tran) => { + // Set the node in the gestalt graph if not already + if ((await gestaltGraph.getGestaltByNode(nodeId, tran)) == null) { + await gestaltGraph.setNode( + { + id: nodesUtils.encodeNodeId(nodeId), + chain: {}, + }, + tran, + ); + // Queue the new node for discovery + await discovery.queueDiscoveryByNode(nodeId); + } + // Set notify permission + await gestaltGraph.setGestaltActionByNode(nodeId, 'notify', tran); + }); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesAuthenticate.ts b/src/client/service/identitiesAuthenticate.ts index 24ccf2f7e..05c3e05d3 100644 --- a/src/client/service/identitiesAuthenticate.ts +++ b/src/client/service/identitiesAuthenticate.ts @@ -1,19 +1,23 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { IdentitiesManager } from '../../identities'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { ProviderId } from '../../identities/types'; -import { utils as grpcUtils } from '../../grpc'; -import { errors as identitiesErrors } from '../../identities'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import * as identitiesErrors from '../../identities/errors'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync, never } from '../../utils'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; function identitiesAuthenticate({ - identitiesManager, authenticate, + identitiesManager, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream< @@ -21,7 +25,7 @@ function identitiesAuthenticate({ identitiesPB.AuthenticationProcess >, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -70,6 +74,7 @@ function identitiesAuthenticate({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesAuthenticatedGet.ts b/src/client/service/identitiesAuthenticatedGet.ts index 1fd4bb9da..82262f89d 100644 --- a/src/client/service/identitiesAuthenticatedGet.ts +++ b/src/client/service/identitiesAuthenticatedGet.ts @@ -1,7 +1,8 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { IdentitiesManager } from '../../identities'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { ProviderId } from '../../identities/types'; +import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; @@ -9,11 +10,13 @@ import * as validationUtils from '../../validation/utils'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; function identitiesAuthenticatedGet({ - identitiesManager, authenticate, + identitiesManager, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream< @@ -21,7 +24,7 @@ function identitiesAuthenticatedGet({ identitiesPB.Provider >, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -60,6 +63,7 @@ function identitiesAuthenticatedGet({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesClaim.ts b/src/client/service/identitiesClaim.ts index 0964ecf78..43919bd45 100644 --- a/src/client/service/identitiesClaim.ts +++ b/src/client/service/identitiesClaim.ts @@ -1,14 +1,17 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type KeyManager from '../../keys/KeyManager'; -import type { Sigchain } from '../../sigchain'; -import type { IdentitiesManager } from '../../identities'; +import type Sigchain from '../../sigchain/Sigchain'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityId, ProviderId } from '../../identities/types'; -import { utils as grpcUtils } from '../../grpc'; -import { utils as claimsUtils } from '../../claims'; -import { utils as nodesUtils } from '../../nodes'; -import { errors as identitiesErrors } from '../../identities'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import * as claimsUtils from '../../claims/utils'; +import * as nodesUtils from '../../nodes/utils'; +import * as identitiesErrors from '../../identities/errors'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; @@ -16,15 +19,19 @@ import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_p * Augments the keynode with a new identity. */ function identitiesClaim({ + authenticate, identitiesManager, sigchain, keyManager, - authenticate, + db, + logger, }: { + authenticate: Authenticate; identitiesManager: IdentitiesManager; sigchain: Sigchain; keyManager: KeyManager; - authenticate: Authenticate; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -63,12 +70,17 @@ function identitiesClaim({ throw new identitiesErrors.ErrorProviderUnauthenticated(); } // Create identity claim on our node - const [, claim] = await sigchain.addClaim({ - type: 'identity', - node: nodesUtils.encodeNodeId(keyManager.getNodeId()), - provider: providerId, - identity: identityId, - }); + const [, claim] = await db.withTransactionF(async (tran) => + sigchain.addClaim( + { + type: 'identity', + node: nodesUtils.encodeNodeId(keyManager.getNodeId()), + provider: providerId, + identity: identityId, + }, + tran, + ), + ); // Publish claim on identity const claimDecoded = claimsUtils.decodeClaim(claim); const claimData = await provider.publishClaim(identityId, claimDecoded); @@ -80,6 +92,7 @@ function identitiesClaim({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesInfoConnectedGet.ts b/src/client/service/identitiesInfoConnectedGet.ts index 399600900..b9d7ac441 100644 --- a/src/client/service/identitiesInfoConnectedGet.ts +++ b/src/client/service/identitiesInfoConnectedGet.ts @@ -1,11 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { IdentitiesManager } from '../../identities'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityData, IdentityId, ProviderId, } from '../../identities/types'; +import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; @@ -14,11 +15,13 @@ import * as identitiesErrors from '../../identities/errors'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; function identitiesInfoConnectedGet({ - identitiesManager, authenticate, + identitiesManager, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream< @@ -26,7 +29,7 @@ function identitiesInfoConnectedGet({ identitiesPB.Info >, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -116,6 +119,7 @@ function identitiesInfoConnectedGet({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesInfoGet.ts b/src/client/service/identitiesInfoGet.ts index bbf159f55..5f456dac5 100644 --- a/src/client/service/identitiesInfoGet.ts +++ b/src/client/service/identitiesInfoGet.ts @@ -1,11 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { IdentitiesManager } from '../../identities'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityData, IdentityId, ProviderId, } from '../../identities/types'; +import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; @@ -15,11 +16,13 @@ import * as identitiesErrors from '../../identities/errors'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; function identitiesInfoGet({ - identitiesManager, authenticate, + identitiesManager, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream< @@ -27,7 +30,7 @@ function identitiesInfoGet({ identitiesPB.Info >, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -109,6 +112,7 @@ function identitiesInfoGet({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesProvidersList.ts b/src/client/service/identitiesProvidersList.ts index a7ce51051..35751c3fb 100644 --- a/src/client/service/identitiesProvidersList.ts +++ b/src/client/service/identitiesProvidersList.ts @@ -1,16 +1,19 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { IdentitiesManager } from '../../identities'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; function identitiesProvidersList({ - identitiesManager, authenticate, + identitiesManager, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -26,6 +29,7 @@ function identitiesProvidersList({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenDelete.ts b/src/client/service/identitiesTokenDelete.ts index 835fee428..82d0d57d5 100644 --- a/src/client/service/identitiesTokenDelete.ts +++ b/src/client/service/identitiesTokenDelete.ts @@ -1,19 +1,26 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { IdentitiesManager } from '../../identities'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityId, ProviderId } from '../../identities/types'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function identitiesTokenDelete({ - identitiesManager, authenticate, + identitiesManager, + db, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -42,11 +49,14 @@ function identitiesTokenDelete({ identityId: call.request.getIdentityId(), }, ); - await identitiesManager.delToken(providerId, identityId); + await db.withTransactionF(async (tran) => + identitiesManager.delToken(providerId, identityId, tran), + ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenGet.ts b/src/client/service/identitiesTokenGet.ts index 102ae3a07..09199866d 100644 --- a/src/client/service/identitiesTokenGet.ts +++ b/src/client/service/identitiesTokenGet.ts @@ -1,18 +1,25 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { IdentitiesManager } from '../../identities'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityId, ProviderId } from '../../identities/types'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; function identitiesTokenGet({ - identitiesManager, authenticate, + identitiesManager, + db, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -41,12 +48,15 @@ function identitiesTokenGet({ identityId: call.request.getIdentityId(), }, ); - const tokens = await identitiesManager.getToken(providerId, identityId); + const tokens = await db.withTransactionF(async (tran) => + identitiesManager.getToken(providerId, identityId, tran), + ); response.setToken(JSON.stringify(tokens)); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenPut.ts b/src/client/service/identitiesTokenPut.ts index 1a371cb95..336f1646a 100644 --- a/src/client/service/identitiesTokenPut.ts +++ b/src/client/service/identitiesTokenPut.ts @@ -1,19 +1,26 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { IdentitiesManager } from '../../identities'; +import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityId, ProviderId, TokenData } from '../../identities/types'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function identitiesTokenPut({ - identitiesManager, authenticate, + identitiesManager, + db, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall< @@ -45,13 +52,21 @@ function identitiesTokenPut({ identityId: call.request.getProvider()?.getIdentityId(), }, ); - await identitiesManager.putToken(providerId, identityId, { - accessToken: call.request.getToken(), - } as TokenData); + await db.withTransactionF(async (tran) => + identitiesManager.putToken( + providerId, + identityId, + { + accessToken: call.request.getToken(), + } as TokenData, + tran, + ), + ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/index.ts b/src/client/service/index.ts index 494c5088c..1e74eb9d8 100644 --- a/src/client/service/index.ts +++ b/src/client/service/index.ts @@ -1,5 +1,6 @@ +import type { DB } from '@matrixai/db'; import type PolykeyAgent from '../../PolykeyAgent'; -import type { KeyManager } from '../../keys'; +import type KeyManager from '../../keys/KeyManager'; import type { VaultManager } from '../../vaults'; import type { NodeManager, @@ -9,7 +10,7 @@ import type { import type { IdentitiesManager } from '../../identities'; import type { GestaltGraph } from '../../gestalts'; import type { SessionManager } from '../../sessions'; -import type { NotificationsManager } from '../../notifications'; +import type NotificationsManager from '../../notifications/NotificationsManager'; import type { Discovery } from '../../discovery'; import type { Sigchain } from '../../sigchain'; import type { GRPCServer } from '../../grpc'; @@ -88,11 +89,13 @@ import { ClientServiceService } from '../../proto/js/polykey/v1/client_service_g function createService({ keyManager, sessionManager, + db, logger = new Logger(createService.name), fs = require('fs'), ...containerRest }: { pkAgent: PolykeyAgent; + db: DB; keyManager: KeyManager; vaultManager: VaultManager; nodeGraph: NodeGraph; @@ -116,6 +119,7 @@ function createService({ ...containerRest, keyManager, sessionManager, + db, logger, fs, authenticate, diff --git a/src/client/service/keysCertsChainGet.ts b/src/client/service/keysCertsChainGet.ts index 8355474fd..6290a313c 100644 --- a/src/client/service/keysCertsChainGet.ts +++ b/src/client/service/keysCertsChainGet.ts @@ -1,21 +1,24 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; +import type KeyManager from '../../keys/KeyManager'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysCertsChainGet({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -30,6 +33,7 @@ function keysCertsChainGet({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/keysCertsGet.ts b/src/client/service/keysCertsGet.ts index 198a67884..eabde463b 100644 --- a/src/client/service/keysCertsGet.ts +++ b/src/client/service/keysCertsGet.ts @@ -1,16 +1,19 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; +import type KeyManager from '../../keys/KeyManager'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysCertsGet({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -26,6 +29,7 @@ function keysCertsGet({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysDecrypt.ts b/src/client/service/keysDecrypt.ts index 0aa84d004..ed1776cda 100644 --- a/src/client/service/keysDecrypt.ts +++ b/src/client/service/keysDecrypt.ts @@ -1,15 +1,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; -import { utils as grpcUtils } from '../../grpc'; +import type KeyManager from '../../keys/KeyManager'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysDecrypt({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -27,6 +30,7 @@ function keysDecrypt({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysEncrypt.ts b/src/client/service/keysEncrypt.ts index 8c048e94c..35159f870 100644 --- a/src/client/service/keysEncrypt.ts +++ b/src/client/service/keysEncrypt.ts @@ -1,15 +1,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; -import { utils as grpcUtils } from '../../grpc'; +import type KeyManager from '../../keys/KeyManager'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysEncrypt({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -27,6 +30,7 @@ function keysEncrypt({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairRenew.ts b/src/client/service/keysKeyPairRenew.ts index ffcd9b5b4..dcd90d7c1 100644 --- a/src/client/service/keysKeyPairRenew.ts +++ b/src/client/service/keysKeyPairRenew.ts @@ -1,16 +1,19 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; +import type KeyManager from '../../keys/KeyManager'; import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function keysKeyPairRenew({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -27,6 +30,7 @@ function keysKeyPairRenew({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairReset.ts b/src/client/service/keysKeyPairReset.ts index a5fee6145..87498f733 100644 --- a/src/client/service/keysKeyPairReset.ts +++ b/src/client/service/keysKeyPairReset.ts @@ -1,16 +1,19 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; +import type KeyManager from '../../keys/KeyManager'; import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function keysKeyPairReset({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -27,6 +30,7 @@ function keysKeyPairReset({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairRoot.ts b/src/client/service/keysKeyPairRoot.ts index 4a5858347..7bfc95549 100644 --- a/src/client/service/keysKeyPairRoot.ts +++ b/src/client/service/keysKeyPairRoot.ts @@ -1,16 +1,19 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; +import type KeyManager from '../../keys/KeyManager'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysKeyPairRoot({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -27,6 +30,7 @@ function keysKeyPairRoot({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysPasswordChange.ts b/src/client/service/keysPasswordChange.ts index 2d5074abf..639e60ac9 100644 --- a/src/client/service/keysPasswordChange.ts +++ b/src/client/service/keysPasswordChange.ts @@ -1,16 +1,19 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; +import type KeyManager from '../../keys/KeyManager'; import type * as sessionsPB from '../../proto/js/polykey/v1/sessions/sessions_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function keysPasswordChange({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -25,6 +28,7 @@ function keysPasswordChange({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysSign.ts b/src/client/service/keysSign.ts index 5f2eee691..b998e0561 100644 --- a/src/client/service/keysSign.ts +++ b/src/client/service/keysSign.ts @@ -1,15 +1,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; -import { utils as grpcUtils } from '../../grpc'; +import type KeyManager from '../../keys/KeyManager'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysSign({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -28,6 +31,7 @@ function keysSign({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysVerify.ts b/src/client/service/keysVerify.ts index 1090642c5..efbfb7b4c 100644 --- a/src/client/service/keysVerify.ts +++ b/src/client/service/keysVerify.ts @@ -1,16 +1,19 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { KeyManager } from '../../keys'; +import type KeyManager from '../../keys/KeyManager'; import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; -import { utils as grpcUtils } from '../../grpc'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function keysVerify({ - keyManager, authenticate, + keyManager, + logger, }: { - keyManager: KeyManager; authenticate: Authenticate; + keyManager: KeyManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -29,6 +32,7 @@ function keysVerify({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/nodesAdd.ts b/src/client/service/nodesAdd.ts index 57924cd5e..1433e0896 100644 --- a/src/client/service/nodesAdd.ts +++ b/src/client/service/nodesAdd.ts @@ -1,11 +1,14 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { NodeManager } from '../../nodes'; +import type NodeManager from '../../nodes/NodeManager'; import type { NodeId, NodeAddress } from '../../nodes/types'; import type { Host, Hostname, Port } from '../../network/types'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; @@ -15,11 +18,15 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; * of the passed ID or host/port. */ function nodesAdd({ - nodeManager, authenticate, + nodeManager, + db, + logger, }: { - nodeManager: NodeManager; authenticate: Authenticate; + nodeManager: NodeManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -52,14 +59,21 @@ function nodesAdd({ port: call.request.getAddress()?.getPort(), }, ); - await nodeManager.setNode(nodeId, { - host, - port, - } as NodeAddress); + await db.withTransactionF(async (tran) => + nodeManager.setNode( + nodeId, + { + host, + port, + } as NodeAddress, + tran, + ), + ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/nodesClaim.ts b/src/client/service/nodesClaim.ts index 280dedb24..4d9cdc783 100644 --- a/src/client/service/nodesClaim.ts +++ b/src/client/service/nodesClaim.ts @@ -1,11 +1,14 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { NodeManager } from '../../nodes'; +import type NodeManager from '../../nodes/NodeManager'; import type { NodeId } from '../../nodes/types'; -import type { NotificationsManager } from '../../notifications'; +import type NotificationsManager from '../../notifications/NotificationsManager'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; @@ -15,13 +18,17 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; * other node and host node. */ function nodesClaim({ + authenticate, nodeManager, notificationsManager, - authenticate, + db, + logger, }: { + authenticate: Authenticate; nodeManager: NodeManager; notificationsManager: NotificationsManager; - authenticate: Authenticate; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -46,25 +53,29 @@ function nodesClaim({ nodeId: call.request.getNodeId(), }, ); - const gestaltInvite = await notificationsManager.findGestaltInvite( - nodeId, - ); - // Check first whether there is an existing gestalt invite from the remote node - // or if we want to force an invitation rather than a claim - if (gestaltInvite === undefined || call.request.getForceInvite()) { - await notificationsManager.sendNotification(nodeId, { - type: 'GestaltInvite', - }); - response.setSuccess(false); - } else { - // There is an existing invitation, and we want to claim the node - await nodeManager.claimNode(nodeId); - response.setSuccess(true); - } + await db.withTransactionF(async (tran) => { + const gestaltInvite = await notificationsManager.findGestaltInvite( + nodeId, + tran, + ); + // Check first whether there is an existing gestalt invite from the remote node + // or if we want to force an invitation rather than a claim + if (gestaltInvite === undefined || call.request.getForceInvite()) { + await notificationsManager.sendNotification(nodeId, { + type: 'GestaltInvite', + }); + response.setSuccess(false); + } else { + // There is an existing invitation, and we want to claim the node + await nodeManager.claimNode(nodeId, tran); + response.setSuccess(true); + } + }); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/nodesFind.ts b/src/client/service/nodesFind.ts index 7982fd9ad..284e50748 100644 --- a/src/client/service/nodesFind.ts +++ b/src/client/service/nodesFind.ts @@ -1,10 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { NodeConnectionManager } from '../../nodes'; +import type NodeConnectionManager from '../../nodes/NodeConnectionManager'; import type { NodeId } from '../../nodes/types'; -import { utils as nodesUtils } from '../../nodes'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as nodesUtils from '../../nodes/utils'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; @@ -14,11 +16,13 @@ import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; * @throws ErrorNodeGraphNodeNotFound if node address cannot be found */ function nodesFind({ - nodeConnectionManager, authenticate, + nodeConnectionManager, + logger, }: { - nodeConnectionManager: NodeConnectionManager; authenticate: Authenticate; + nodeConnectionManager: NodeConnectionManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -53,6 +57,7 @@ function nodesFind({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/nodesPing.ts b/src/client/service/nodesPing.ts index 7dfd89939..449905cc7 100644 --- a/src/client/service/nodesPing.ts +++ b/src/client/service/nodesPing.ts @@ -1,10 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { NodeManager } from '../../nodes'; +import type NodeManager from '../../nodes/NodeManager'; import type { NodeId } from '../../nodes/types'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; @@ -12,11 +14,13 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; * Checks if a remote node is online. */ function nodesPing({ - nodeManager, authenticate, + nodeManager, + logger, }: { - nodeManager: NodeManager; authenticate: Authenticate; + nodeManager: NodeManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -47,6 +51,7 @@ function nodesPing({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/notificationsClear.ts b/src/client/service/notificationsClear.ts index 322f64cf6..56b2fabef 100644 --- a/src/client/service/notificationsClear.ts +++ b/src/client/service/notificationsClear.ts @@ -1,15 +1,21 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { NotificationsManager } from '../../notifications'; -import { utils as grpcUtils } from '../../grpc'; +import type NotificationsManager from '../../notifications/NotificationsManager'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function notificationsClear({ - notificationsManager, authenticate, + notificationsManager, + db, + logger, }: { - notificationsManager: NotificationsManager; authenticate: Authenticate; + notificationsManager: NotificationsManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -19,11 +25,14 @@ function notificationsClear({ const response = new utilsPB.EmptyMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - await notificationsManager.clearNotifications(); + await db.withTransactionF(async (tran) => + notificationsManager.clearNotifications(tran), + ); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/notificationsRead.ts b/src/client/service/notificationsRead.ts index e890ce6c0..63b94438d 100644 --- a/src/client/service/notificationsRead.ts +++ b/src/client/service/notificationsRead.ts @@ -1,15 +1,21 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { NotificationsManager } from '../../notifications'; -import { utils as grpcUtils } from '../../grpc'; +import type NotificationsManager from '../../notifications/NotificationsManager'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; import * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifications_pb'; function notificationsRead({ - notificationsManager, authenticate, + notificationsManager, + db, + logger, }: { - notificationsManager: NotificationsManager; authenticate: Authenticate; + notificationsManager: NotificationsManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -28,11 +34,14 @@ function notificationsRead({ } else { number = parseInt(numberField); } - const notifications = await notificationsManager.readNotifications({ - unread, - number, - order, - }); + const notifications = await db.withTransactionF(async (tran) => + notificationsManager.readNotifications({ + unread, + number, + order, + tran, + }), + ); const notifMessages: Array = []; for (const notif of notifications) { const notificationsMessage = new notificationsPB.Notification(); @@ -65,6 +74,7 @@ function notificationsRead({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/notificationsSend.ts b/src/client/service/notificationsSend.ts index ed3b26e05..4ff96fea6 100644 --- a/src/client/service/notificationsSend.ts +++ b/src/client/service/notificationsSend.ts @@ -1,20 +1,24 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; -import type { NotificationsManager } from '../../notifications'; +import type NotificationsManager from '../../notifications/NotificationsManager'; import type { NodeId } from '../../nodes/types'; import type * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifications_pb'; -import { utils as grpcUtils } from '../../grpc'; -import { utils as notificationsUtils } from '../../notifications'; -import { validateSync, utils as validationUtils } from '../../validation'; +import type Logger from '@matrixai/logger'; +import * as grpcUtils from '../../grpc/utils'; +import * as notificationsUtils from '../../notifications/utils'; +import { validateSync } from '../../validation'; +import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function notificationsSend({ - notificationsManager, authenticate, + notificationsManager, + logger, }: { - notificationsManager: NotificationsManager; authenticate: Authenticate; + notificationsManager: NotificationsManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -50,6 +54,7 @@ function notificationsSend({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsClone.ts b/src/client/service/vaultsClone.ts index a35d70e7f..bd3693c5c 100644 --- a/src/client/service/vaultsClone.ts +++ b/src/client/service/vaultsClone.ts @@ -1,6 +1,8 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; @@ -10,9 +12,13 @@ import * as vaultsUtils from '../../vaults/utils'; function vaultsClone({ authenticate, vaultManager, + db, + logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -40,12 +46,15 @@ function vaultsClone({ vaultId = vaultId ?? vaultNameOrId; // Node id const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId()); - await vaultManager.cloneVault(nodeId, vaultId); + await db.withTransactionF(async (tran) => + vaultManager.cloneVault(nodeId, vaultId, tran), + ); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsCreate.ts b/src/client/service/vaultsCreate.ts index 363e4a200..a739604e7 100644 --- a/src/client/service/vaultsCreate.ts +++ b/src/client/service/vaultsCreate.ts @@ -2,17 +2,23 @@ import type { Authenticate } from '../types'; import type { VaultId, VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsUtils from '../../vaults/utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsCreate({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -23,14 +29,15 @@ function vaultsCreate({ try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - vaultId = await vaultManager.createVault( - call.request.getNameOrId() as VaultName, + vaultId = await db.withTransactionF(async (tran) => + vaultManager.createVault(call.request.getNameOrId() as VaultName, tran), ); response.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsDelete.ts b/src/client/service/vaultsDelete.ts index d2f029c4a..7a87f2da0 100644 --- a/src/client/service/vaultsDelete.ts +++ b/src/client/service/vaultsDelete.ts @@ -2,17 +2,23 @@ import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; import * as validationUtils from '../../validation/utils'; function vaultsDelete({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -24,14 +30,20 @@ function vaultsDelete({ const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - await vaultManager.destroyVault(vaultId); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + await vaultManager.destroyVault(vaultId, tran); + }); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsList.ts b/src/client/service/vaultsList.ts index d81902976..a4a618275 100644 --- a/src/client/service/vaultsList.ts +++ b/src/client/service/vaultsList.ts @@ -1,29 +1,34 @@ import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsUtils from '../../vaults/utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsList({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - // Call.on('error', (e) => console.error(e)); - // call.on('close', () => console.log('Got close')); - // call.on('finish', () => console.log('Got finish')); - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaults = await vaultManager.listVaults(); + const vaults = await db.withTransactionF(async (tran) => + vaultManager.listVaults(tran), + ); for await (const [vaultName, vaultId] of vaults) { const vaultListMessage = new vaultsPB.List(); vaultListMessage.setVaultName(vaultName); @@ -34,6 +39,7 @@ function vaultsList({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsLog.ts b/src/client/service/vaultsLog.ts index 99056911a..367dd0a1e 100644 --- a/src/client/service/vaultsLog.ts +++ b/src/client/service/vaultsLog.ts @@ -1,6 +1,8 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb'; import * as grpcUtils from '../../grpc/utils'; @@ -8,16 +10,20 @@ import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; import * as validationUtils from '../../validation/utils'; function vaultsLog({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -29,14 +35,23 @@ function vaultsLog({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - // Getting the log - const depth = vaultsLogMessage.getLogDepth(); - let commitId: string | undefined = vaultsLogMessage.getCommitId(); - commitId = commitId ? commitId : undefined; - const log = await vaultManager.withVaults([vaultId], async (vault) => { - return await vault.log(commitId, depth); + const log = await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + // Getting the log + const depth = vaultsLogMessage.getLogDepth(); + let commitId: string | undefined = vaultsLogMessage.getCommitId(); + commitId = commitId ? commitId : undefined; + return await vaultManager.withVaults( + [vaultId], + async (vault) => { + return await vault.log(commitId, depth); + }, + tran, + ); }); const vaultsLogEntryMessage = new vaultsPB.LogEntry(); for (const entry of log) { @@ -52,6 +67,7 @@ function vaultsLog({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsPermissionGet.ts b/src/client/service/vaultsPermissionGet.ts index 23780000e..8e62be35a 100644 --- a/src/client/service/vaultsPermissionGet.ts +++ b/src/client/service/vaultsPermissionGet.ts @@ -1,10 +1,12 @@ +import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; import type { VaultName } from '../../vaults/types'; -import type * as grpc from '@grpc/grpc-js'; import type { VaultActions } from '../../vaults/types'; import type ACL from '../../acl/ACL'; import type { NodeId, NodeIdEncoded } from 'nodes/types'; +import type Logger from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; import * as grpcUtils from '../../grpc/utils'; import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; @@ -16,26 +18,36 @@ function vaultsPermissionGet({ authenticate, vaultManager, acl, + db, + logger, }: { authenticate: Authenticate; vaultManager: VaultManager; acl: ACL; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const vaultMessage = call.request; const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); // Getting vaultId const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - - // Getting permissions - const rawPermissions = await acl.getVaultPerm(vaultId); + const [rawPermissions, vaultId] = await db.withTransactionF( + async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + // Getting permissions + return [await acl.getVaultPerm(vaultId, tran), vaultId]; + }, + ); const permissionList: Record = {}; // Getting the relevant information for (const nodeId in rawPermissions) { @@ -57,8 +69,9 @@ function vaultsPermissionGet({ } await genWritable.next(null); return; - } catch (err) { - await genWritable.throw(err); + } catch (e) { + await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsPermissionSet.ts b/src/client/service/vaultsPermissionSet.ts index 6b4768ee8..f91ccd81f 100644 --- a/src/client/service/vaultsPermissionSet.ts +++ b/src/client/service/vaultsPermissionSet.ts @@ -1,3 +1,4 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; @@ -6,6 +7,7 @@ import type ACL from '../../acl/ACL'; import type NotificationsManager from '../../notifications/NotificationsManager'; import type { VaultActions } from '../../vaults/types'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; @@ -14,17 +16,21 @@ import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsPermissionSet({ - vaultManager, authenticate, + vaultManager, gestaltGraph, acl, notificationsManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; gestaltGraph: GestaltGraph; acl: ACL; notificationsManager: NotificationsManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -41,32 +47,37 @@ function vaultsPermissionSet({ callback({ code: grpc.status.NOT_FOUND }, null); return; } - // Parsing VaultId - const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - // Parsing NodeId - const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId()); - // Parsing actions - const actions = vaultsPermissionsMessage - .getVaultPermissionsList() - .map((vaultAction) => validationUtils.parseVaultAction(vaultAction)); - // Checking if vault exists - const vaultMeta = await vaultManager.getVaultMeta(vaultId); - if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined(); - // Setting permissions - const actionsSet: VaultActions = {}; - await gestaltGraph.setGestaltActionByNode(nodeId, 'scan'); - for (const action of actions) { - await acl.setVaultAction(vaultId, nodeId, action); - actionsSet[action] = null; - } - // Sending notification - await notificationsManager.sendNotification(nodeId, { - type: 'VaultShare', - vaultId: vaultsUtils.encodeVaultId(vaultId), - vaultName: vaultMeta.vaultName, - actions: actionsSet, + await db.withTransactionF(async (tran) => { + // Parsing VaultId + const nameOrId = vaultMessage.getNameOrId(); + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + // Parsing NodeId + const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId()); + // Parsing actions + const actions = vaultsPermissionsMessage + .getVaultPermissionsList() + .map((vaultAction) => validationUtils.parseVaultAction(vaultAction)); + // Checking if vault exists + const vaultMeta = await vaultManager.getVaultMeta(vaultId, tran); + if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined(); + // Setting permissions + const actionsSet: VaultActions = {}; + await gestaltGraph.setGestaltActionByNode(nodeId, 'scan', tran); + for (const action of actions) { + await acl.setVaultAction(vaultId, nodeId, action, tran); + actionsSet[action] = null; + } + // Sending notification + await notificationsManager.sendNotification(nodeId, { + type: 'VaultShare', + vaultId: vaultsUtils.encodeVaultId(vaultId), + vaultName: vaultMeta.vaultName, + actions: actionsSet, + }); }); // Formatting response const response = new utilsPB.StatusMessage().setSuccess(true); @@ -74,6 +85,7 @@ function vaultsPermissionSet({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsPermissionUnset.ts b/src/client/service/vaultsPermissionUnset.ts index d16d81d98..8095e21c4 100644 --- a/src/client/service/vaultsPermissionUnset.ts +++ b/src/client/service/vaultsPermissionUnset.ts @@ -1,9 +1,11 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type ACL from '../../acl/ACL'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as vaultsErrors from '../../vaults/errors'; import * as validationUtils from '../../validation/utils'; @@ -11,15 +13,19 @@ import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsPermissionUnset({ - vaultManager, authenticate, + vaultManager, gestaltGraph, acl, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; gestaltGraph: GestaltGraph; acl: ACL; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -36,43 +42,46 @@ function vaultsPermissionUnset({ callback({ code: grpc.status.NOT_FOUND }, null); return; } - // Parsing VaultId - const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - // Parsing NodeId - const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId()); - // Parsing actions - const actions = vaultsPermissionsMessage - .getVaultPermissionsList() - .map((vaultAction) => validationUtils.parseVaultAction(vaultAction)); - // Checking if vault exists - const vaultMeta = await vaultManager.getVaultMeta(vaultId); - if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined(); - // Unsetting permissions - await gestaltGraph.setGestaltActionByNode(nodeId, 'scan'); - for (const action of actions) { - await acl.unsetVaultAction(vaultId, nodeId, action); - } - // We need to check if there are still shared vaults - const nodePermissions = await acl.getNodePerm(nodeId); - // Remove scan permissions if no more shared vaults - if (nodePermissions != null) { - // Counting total number of permissions - const totalPermissions = Object.keys(nodePermissions.vaults) - .map((key) => Object.keys(nodePermissions.vaults[key]).length) - .reduce((prev, current) => current + prev); - // If no permissions are left then we remove the scan permission - if (totalPermissions === 0) { - await gestaltGraph.unsetGestaltActionByNode(nodeId, 'scan'); + await db.withTransactionF(async (tran) => { + // Parsing VaultId + const nameOrId = vaultMessage.getNameOrId(); + let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + // Parsing NodeId + const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId()); + // Parsing actions + const actions = vaultsPermissionsMessage + .getVaultPermissionsList() + .map((vaultAction) => validationUtils.parseVaultAction(vaultAction)); + // Checking if vault exists + const vaultMeta = await vaultManager.getVaultMeta(vaultId, tran); + if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined(); + // Unsetting permissions + await gestaltGraph.setGestaltActionByNode(nodeId, 'scan', tran); + for (const action of actions) { + await acl.unsetVaultAction(vaultId, nodeId, action, tran); } - } + // We need to check if there are still shared vaults + const nodePermissions = await acl.getNodePerm(nodeId, tran); + // Remove scan permissions if no more shared vaults + if (nodePermissions != null) { + // Counting total number of permissions + const totalPermissions = Object.keys(nodePermissions.vaults) + .map((key) => Object.keys(nodePermissions.vaults[key]).length) + .reduce((prev, current) => current + prev); + // If no permissions are left then we remove the scan permission + if (totalPermissions === 0) { + await gestaltGraph.unsetGestaltActionByNode(nodeId, 'scan', tran); + } + } + }); // Formatting response const response = new utilsPB.StatusMessage().setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsPull.ts b/src/client/service/vaultsPull.ts index 8c18e1a29..f68a62903 100644 --- a/src/client/service/vaultsPull.ts +++ b/src/client/service/vaultsPull.ts @@ -1,7 +1,9 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; import type { VaultName } from '../../vaults/types'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; @@ -11,9 +13,13 @@ import * as vaultsUtils from '../../vaults/utils'; function vaultsPull({ authenticate, vaultManager, + db, + logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -30,34 +36,41 @@ function vaultsPull({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - let nodeId; - const nodeMessage = call.request.getNode(); - if (nodeMessage == null) { - nodeId = null; - } else { - nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId()); - } - let pullVault; - const pullVaultMessage = call.request.getPullVault(); - if (pullVaultMessage == null) { - pullVault = null; - } else { - pullVault = vaultsUtils.decodeVaultId(pullVaultMessage.getNameOrId()); - pullVault = pullVault ?? pullVaultMessage.getNameOrId(); - if (pullVault == null) pullVault = pullVaultMessage.getNameOrId(); - } - await vaultManager.pullVault({ - vaultId, - pullNodeId: nodeId, - pullVaultNameOrId: pullVault, + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + let nodeId; + const nodeMessage = call.request.getNode(); + if (nodeMessage == null) { + nodeId = null; + } else { + nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId()); + } + let pullVault; + const pullVaultMessage = call.request.getPullVault(); + if (pullVaultMessage == null) { + pullVault = null; + } else { + pullVault = vaultsUtils.decodeVaultId(pullVaultMessage.getNameOrId()); + pullVault = pullVault ?? pullVaultMessage.getNameOrId(); + if (pullVault == null) pullVault = pullVaultMessage.getNameOrId(); + } + await vaultManager.pullVault({ + vaultId, + pullNodeId: nodeId, + pullVaultNameOrId: pullVault, + tran, + }); }); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsRename.ts b/src/client/service/vaultsRename.ts index 506162989..0689b2506 100644 --- a/src/client/service/vaultsRename.ts +++ b/src/client/service/vaultsRename.ts @@ -1,6 +1,8 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -8,11 +10,15 @@ import * as vaultsUtils from '../../vaults/utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsRename({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -28,15 +34,21 @@ function vaultsRename({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const newName = call.request.getNewName() as VaultName; - await vaultManager.renameVault(vaultId, newName); - response.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const newName = call.request.getNewName() as VaultName; + await vaultManager.renameVault(vaultId, newName); + response.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + }); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsScan.ts b/src/client/service/vaultsScan.ts index 3d8d73a7e..f0392dba5 100644 --- a/src/client/service/vaultsScan.ts +++ b/src/client/service/vaultsScan.ts @@ -3,6 +3,7 @@ import type { NodeId } from '../../nodes/types'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; import type * as grpc from '@grpc/grpc-js'; import type VaultManager from '../../vaults/VaultManager'; +import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; @@ -10,16 +11,18 @@ import { matchSync } from '../../utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsScan({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -53,6 +56,7 @@ function vaultsScan({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsDelete.ts b/src/client/service/vaultsSecretsDelete.ts index 07a56a92d..46784f9fe 100644 --- a/src/client/service/vaultsSecretsDelete.ts +++ b/src/client/service/vaultsSecretsDelete.ts @@ -1,7 +1,9 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -9,11 +11,15 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsDelete({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -29,17 +35,27 @@ function vaultsSecretsDelete({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const secretName = call.request.getSecretName(); - await vaultManager.withVaults([vaultId], async (vault) => { - await vaultOps.deleteSecret(vault, secretName); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const secretName = call.request.getSecretName(); + await vaultManager.withVaults( + [vaultId], + async (vault) => { + await vaultOps.deleteSecret(vault, secretName); + }, + tran, + ); }); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsEdit.ts b/src/client/service/vaultsSecretsEdit.ts index 8f45362b2..897a6dd12 100644 --- a/src/client/service/vaultsSecretsEdit.ts +++ b/src/client/service/vaultsSecretsEdit.ts @@ -1,7 +1,9 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -9,11 +11,15 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsEdit({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -34,18 +40,28 @@ function vaultsSecretsEdit({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const secretName = secretMessage.getSecretName(); - const secretContent = Buffer.from(secretMessage.getSecretContent()); - await vaultManager.withVaults([vaultId], async (vault) => { - await vaultOps.updateSecret(vault, secretName, secretContent); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const secretName = secretMessage.getSecretName(); + const secretContent = Buffer.from(secretMessage.getSecretContent()); + await vaultManager.withVaults( + [vaultId], + async (vault) => { + await vaultOps.updateSecret(vault, secretName, secretContent); + }, + tran, + ); }); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsGet.ts b/src/client/service/vaultsSecretsGet.ts index fa836e1b0..cdb2a75fb 100644 --- a/src/client/service/vaultsSecretsGet.ts +++ b/src/client/service/vaultsSecretsGet.ts @@ -1,7 +1,9 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -9,11 +11,15 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; function vaultsSecretsGet({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -29,20 +35,27 @@ function vaultsSecretsGet({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const secretName = call.request.getSecretName(); - const secretContent = await vaultManager.withVaults( - [vaultId], - async (vault) => { - return await vaultOps.getSecret(vault, secretName); - }, - ); - response.setSecretContent(secretContent); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const secretName = call.request.getSecretName(); + const secretContent = await vaultManager.withVaults( + [vaultId], + async (vault) => { + return await vaultOps.getSecret(vault, secretName); + }, + tran, + ); + response.setSecretContent(secretContent); + }); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsList.ts b/src/client/service/vaultsSecretsList.ts index db2a1cc36..8056c7a90 100644 --- a/src/client/service/vaultsSecretsList.ts +++ b/src/client/service/vaultsSecretsList.ts @@ -2,36 +2,48 @@ import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import type Logger from '@matrixai/logger'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; function vaultsSecretsList({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); const vaultMessage = call.request; const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const secrets = await vaultManager.withVaults( - [vaultId], - async (vault) => { - return await vaultOps.listSecrets(vault); - }, - ); + const secrets = await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + return await vaultManager.withVaults( + [vaultId], + async (vault) => { + return await vaultOps.listSecrets(vault); + }, + tran, + ); + }); let secretMessage: secretsPB.Secret; for (const secret of secrets) { secretMessage = new secretsPB.Secret(); @@ -42,6 +54,7 @@ function vaultsSecretsList({ return; } catch (e) { await genWritable.throw(e); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsMkdir.ts b/src/client/service/vaultsSecretsMkdir.ts index fca32d4f9..6d5649fb5 100644 --- a/src/client/service/vaultsSecretsMkdir.ts +++ b/src/client/service/vaultsSecretsMkdir.ts @@ -1,7 +1,9 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -9,11 +11,15 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsMkdir({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -30,18 +36,28 @@ function vaultsSecretsMkdir({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - await vaultManager.withVaults([vaultId], async (vault) => { - await vaultOps.mkdir(vault, vaultMkdirMessge.getDirName(), { - recursive: vaultMkdirMessge.getRecursive(), - }); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + await vaultManager.withVaults( + [vaultId], + async (vault) => { + await vaultOps.mkdir(vault, vaultMkdirMessge.getDirName(), { + recursive: vaultMkdirMessge.getRecursive(), + }); + }, + tran, + ); }); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsNew.ts b/src/client/service/vaultsSecretsNew.ts index 3c22baa7a..0a6c1920c 100644 --- a/src/client/service/vaultsSecretsNew.ts +++ b/src/client/service/vaultsSecretsNew.ts @@ -1,7 +1,9 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -9,11 +11,15 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsNew({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -29,18 +35,28 @@ function vaultsSecretsNew({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const secret = call.request.getSecretName(); - const content = Buffer.from(call.request.getSecretContent()); - await vaultManager.withVaults([vaultId], async (vault) => { - await vaultOps.addSecret(vault, secret, content); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const secret = call.request.getSecretName(); + const content = Buffer.from(call.request.getSecretContent()); + await vaultManager.withVaults( + [vaultId], + async (vault) => { + await vaultOps.addSecret(vault, secret, content); + }, + tran, + ); }); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsNewDir.ts b/src/client/service/vaultsSecretsNewDir.ts index 31a075e01..daf151f58 100644 --- a/src/client/service/vaultsSecretsNewDir.ts +++ b/src/client/service/vaultsSecretsNewDir.ts @@ -1,8 +1,10 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type { FileSystem } from '../../types'; import type * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -10,13 +12,17 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsNewDir({ - vaultManager, authenticate, + vaultManager, fs, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; fs: FileSystem; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -32,17 +38,27 @@ function vaultsSecretsNewDir({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const secretsPath = call.request.getSecretDirectory(); - await vaultManager.withVaults([vaultId], async (vault) => { - await vaultOps.addSecretDirectory(vault, secretsPath, fs); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const secretsPath = call.request.getSecretDirectory(); + await vaultManager.withVaults( + [vaultId], + async (vault) => { + await vaultOps.addSecretDirectory(vault, secretsPath, fs); + }, + tran, + ); }); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsRename.ts b/src/client/service/vaultsSecretsRename.ts index 7de527519..fabe0512c 100644 --- a/src/client/service/vaultsSecretsRename.ts +++ b/src/client/service/vaultsSecretsRename.ts @@ -1,7 +1,9 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -9,11 +11,15 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsRename({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -34,18 +40,28 @@ function vaultsSecretsRename({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const oldSecret = secretMessage.getSecretName(); - const newSecret = call.request.getNewName(); - await vaultManager.withVaults([vaultId], async (vault) => { - await vaultOps.renameSecret(vault, oldSecret, newSecret); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const oldSecret = secretMessage.getSecretName(); + const newSecret = call.request.getNewName(); + await vaultManager.withVaults( + [vaultId], + async (vault) => { + await vaultOps.renameSecret(vault, oldSecret, newSecret); + }, + tran, + ); }); response.setSuccess(true); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsStat.ts b/src/client/service/vaultsSecretsStat.ts index e657d4009..d30b1e20f 100644 --- a/src/client/service/vaultsSecretsStat.ts +++ b/src/client/service/vaultsSecretsStat.ts @@ -1,6 +1,8 @@ +import type { DB } from '@matrixai/db'; import type VaultManager from '../../vaults/VaultManager'; import type { VaultName } from '../../vaults/types'; import type { Authenticate } from '../types'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; @@ -10,9 +12,13 @@ import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; function vaultsSecretsStat({ authenticate, vaultManager, + db, + logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -28,17 +34,27 @@ function vaultsSecretsStat({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const secretName = call.request.getSecretName(); - const stat = await vaultManager.withVaults([vaultId], async (vault) => { - return await vaultOps.statSecret(vault, secretName); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const secretName = call.request.getSecretName(); + const stat = await vaultManager.withVaults( + [vaultId], + async (vault) => { + return await vaultOps.statSecret(vault, secretName); + }, + tran, + ); + response.setJson(JSON.stringify(stat)); }); - response.setJson(JSON.stringify(stat)); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/vaultsVersion.ts b/src/client/service/vaultsVersion.ts index 4338966da..18868456b 100644 --- a/src/client/service/vaultsVersion.ts +++ b/src/client/service/vaultsVersion.ts @@ -1,17 +1,23 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; +import type Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsVersion({ - vaultManager, authenticate, + vaultManager, + db, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + db: DB; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -30,28 +36,36 @@ function vaultsVersion({ return; } const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId(nameOrId as VaultName); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - // Doing the deed - const versionId = vaultsVersionMessage.getVersionId(); - const [latestOid, currentVersionId] = await vaultManager.withVaults( - [vaultId], - async (vault) => { - const latestOid = (await vault.log())[0].commitId; - await vault.version(versionId); - const currentVersionId = (await vault.log(versionId, 0))[0]?.commitId; - return [latestOid, currentVersionId]; - }, - ); - // Checking if latest version ID - const isLatestVersion = latestOid === currentVersionId; - // Creating message - response.setIsLatestVersion(isLatestVersion); + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + nameOrId as VaultName, + tran, + ); + vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + // Doing the deed + const versionId = vaultsVersionMessage.getVersionId(); + const [latestOid, currentVersionId] = await vaultManager.withVaults( + [vaultId], + async (vault) => { + const latestOid = (await vault.log())[0].commitId; + await vault.version(versionId); + const currentVersionId = (await vault.log(versionId, 0))[0] + ?.commitId; + return [latestOid, currentVersionId]; + }, + tran, + ); + // Checking if latest version ID + const isLatestVersion = latestOid === currentVersionId; + // Creating message + response.setIsLatestVersion(isLatestVersion); + }); // Sending message callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/utils/utils.ts b/src/client/utils/utils.ts index 3e2021cf9..d49173a6f 100644 --- a/src/client/utils/utils.ts +++ b/src/client/utils/utils.ts @@ -3,12 +3,13 @@ import type { Interceptor, InterceptorOptions, } from '@grpc/grpc-js/build/src/client-interceptors'; -import type { KeyManager } from '../../keys'; -import type { Session, SessionManager } from '../../sessions'; +import type KeyManager from '../../keys/KeyManager'; +import type Session from '../../sessions/Session'; +import type SessionManager from '../../sessions/SessionManager'; import type { SessionToken } from '../../sessions/types'; import type { Authenticate } from '../types'; -import * as grpc from '@grpc/grpc-js'; import * as base64 from 'multiformats/bases/base64'; +import * as grpc from '@grpc/grpc-js'; import * as clientErrors from '../errors'; /** @@ -129,7 +130,7 @@ function decodeAuthToSession( if (auth == null || !auth.startsWith('Bearer ')) { return; } - return auth.substr(7) as SessionToken; + return auth.substring(7) as SessionToken; } export { diff --git a/src/discovery/Discovery.ts b/src/discovery/Discovery.ts index 900b6b63f..53026b098 100644 --- a/src/discovery/Discovery.ts +++ b/src/discovery/Discovery.ts @@ -1,5 +1,4 @@ -import type { MutexInterface } from 'async-mutex'; -import type { DB, DBLevel } from '@matrixai/db'; +import type { DB, LevelPath } from '@matrixai/db'; import type { DiscoveryQueueId, DiscoveryQueueIdGenerator } from './types'; import type { NodeId, NodeInfo } from '../nodes/types'; import type NodeManager from '../nodes/NodeManager'; @@ -14,12 +13,10 @@ import type { IdentityClaimId, IdentityClaims, } from '../identities/types'; -import type { Sigchain } from '../sigchain'; -import type { KeyManager } from '../keys'; +import type Sigchain from '../sigchain/Sigchain'; +import type KeyManager from '../keys/KeyManager'; import type { ClaimIdEncoded, Claim, ClaimLinkIdentity } from '../claims/types'; import type { ChainData } from '../sigchain/types'; -import type { ResourceAcquire } from '../utils'; -import { Mutex } from 'async-mutex'; import Logger from '@matrixai/logger'; import { CreateDestroyStartStop, @@ -27,14 +24,17 @@ import { status, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { IdInternal } from '@matrixai/id'; +import { Lock } from '@matrixai/async-locks'; import * as idUtils from '@matrixai/id/dist/utils'; +import { utils as DBUtils } from '@matrixai/db'; +import * as resources from '@matrixai/resources'; import * as discoveryUtils from './utils'; import * as discoveryErrors from './errors'; import * as nodesErrors from '../nodes/errors'; -import * as utils from '../utils'; import * as gestaltsUtils from '../gestalts/utils'; import * as claimsUtils from '../claims/utils'; import * as nodesUtils from '../nodes/utils'; +import { never, promise } from '../utils'; interface Discovery extends CreateDestroyStartStop {} @CreateDestroyStartStop( @@ -83,20 +83,15 @@ class Discovery { protected gestaltGraph: GestaltGraph; protected identitiesManager: IdentitiesManager; protected nodeManager: NodeManager; - protected discoveryDbDomain: string = this.constructor.name; - protected discoveryQueueDbDomain: Array = [ - this.discoveryDbDomain, - 'queue', - ]; - protected discoveryDb: DBLevel; - protected discoveryQueueDb: DBLevel; - protected lock: Mutex = new Mutex(); + + protected discoveryDbPath: LevelPath = [this.constructor.name]; + protected discoveryQueueDbPath: LevelPath = [this.constructor.name, 'queue']; protected discoveryQueueIdGenerator: DiscoveryQueueIdGenerator; protected visitedVertices = new Set(); - protected discoveryQueue: AsyncGenerator; protected discoveryProcess: Promise; - protected queuePlug: Mutex = new Mutex(); - protected queuePlugRelease: MutexInterface.Releaser | undefined; + protected queuePlug = promise(); + protected queueDrained = promise(); + protected lock: Lock = new Lock(); public constructor({ keyManager, @@ -130,60 +125,43 @@ class Discovery { fresh?: boolean; } = {}): Promise { this.logger.info(`Starting ${this.constructor.name}`); - const discoveryDb = await this.db.level(this.discoveryDbDomain); - // Queue stores DiscoveryQueueId -> GestaltKey - const discoveryQueueDb = await this.db.level( - this.discoveryQueueDbDomain[1], - discoveryDb, - ); if (fresh) { - await discoveryDb.clear(); + await this.db.clear(this.discoveryDbPath); } - this.discoveryDb = discoveryDb; - this.discoveryQueueDb = discoveryQueueDb; // Getting latest ID and creating ID generator let latestId: DiscoveryQueueId | undefined; - const keyStream = this.discoveryQueueDb.createKeyStream({ - limit: 1, - reverse: true, - }); - for await (const o of keyStream) { - latestId = IdInternal.fromBuffer(o); + const keyIterator = this.db.iterator( + { limit: 1, reverse: true, values: false }, + this.discoveryQueueDbPath, + ); + for await (const [key] of keyIterator) { + latestId = IdInternal.fromBuffer(key); } this.discoveryQueueIdGenerator = discoveryUtils.createDiscoveryQueueIdGenerator(latestId); - this.discoveryQueue = this.setupDiscoveryQueue(); - this.discoveryProcess = this.runDiscoveryQueue(); + // Starting the queue + this.discoveryProcess = this.setupDiscoveryQueue(); this.logger.info(`Started ${this.constructor.name}`); } public async stop(): Promise { this.logger.info(`Stopping ${this.constructor.name}`); - if (this.queuePlugRelease != null) { - this.queuePlugRelease(); - } - await this.discoveryQueue.return(); + this.queuePlug.resolveP(); await this.discoveryProcess; this.logger.info(`Stopped ${this.constructor.name}`); } - public async destroy() { + public async destroy(): Promise { this.logger.info(`Destroying ${this.constructor.name}`); - const discoveryDb = await this.db.level(this.discoveryDbDomain); - await discoveryDb.clear(); + await this.db.clear(this.discoveryDbPath); this.logger.info(`Destroyed ${this.constructor.name}`); } - public transaction: ResourceAcquire = async () => { - const release = await this.lock.acquire(); - return [async () => release(), this]; - }; - /** * Queues a node for discovery. Internally calls `pushKeyToDiscoveryQueue`. */ @ready(new discoveryErrors.ErrorDiscoveryNotRunning()) - public async queueDiscoveryByNode(nodeId: NodeId) { + public async queueDiscoveryByNode(nodeId: NodeId): Promise { const nodeKey = gestaltsUtils.keyFromNode(nodeId); await this.pushKeyToDiscoveryQueue(nodeKey); } @@ -196,87 +174,196 @@ class Discovery { public async queueDiscoveryByIdentity( providerId: ProviderId, identityId: IdentityId, - ) { + ): Promise { const identityKey = gestaltsUtils.keyFromIdentity(providerId, identityId); await this.pushKeyToDiscoveryQueue(identityKey); } /** - * Generator for the logic of iterating through the Discovery Queue. + * Async function for processing the Discovery Queue */ - public async *setupDiscoveryQueue(): AsyncGenerator { + public async setupDiscoveryQueue(): Promise { + this.logger.debug('Setting up DiscoveryQueue'); while (true) { - if (!(await this.queueIsEmpty())) { - for await (const o of this.discoveryQueueDb.createReadStream()) { - const vertexId = IdInternal.fromBuffer(o.key) as DiscoveryQueueId; - const data = o.value as Buffer; - const vertex = await this.db.deserializeDecrypt( - data, - false, - ); - const vertexGId = gestaltsUtils.ungestaltKey(vertex); - if (vertexGId.type === 'node') { - // The sigchain data of the vertex (containing all cryptolinks) - let vertexChainData: ChainData = {}; - // If the vertex we've found is our own node, we simply get our own chain - const nodeId = nodesUtils.decodeNodeId(vertexGId.nodeId)!; - if (nodeId.equals(this.keyManager.getNodeId())) { - const vertexChainDataEncoded = await this.sigchain.getChainData(); - // Decode all our claims - no need to verify (on our own sigchain) - for (const c in vertexChainDataEncoded) { - const claimId = c as ClaimIdEncoded; - vertexChainData[claimId] = claimsUtils.decodeClaim( - vertexChainDataEncoded[claimId], - ); + // Checking and waiting for items to process + if (await this.queueIsEmpty()) { + if (!(this[status] === 'stopping')) { + this.queuePlug = promise(); + this.queueDrained.resolveP(); + } + this.logger.debug('DiscoveryQueue is pausing'); + await this.queuePlug.p; + this.queueDrained = promise(); + } + if (this[status] === 'stopping') { + this.logger.debug('DiscoveryQueue is ending'); + break; + } + + // Processing queue + this.logger.debug('DiscoveryQueue is processing'); + for await (const [key, value] of this.db.iterator( + {}, + this.discoveryQueueDbPath, + )) { + const vertexId = IdInternal.fromBuffer(key) as DiscoveryQueueId; + const vertex = DBUtils.deserialize(value); + this.logger.debug(`Processing vertex: ${vertex}`); + const vertexGId = gestaltsUtils.ungestaltKey(vertex); + switch (vertexGId.type) { + case 'node': + { + // The sigChain data of the vertex (containing all cryptolinks) + let vertexChainData: ChainData = {}; + // If the vertex we've found is our own node, we simply get our own chain + const nodeId = nodesUtils.decodeNodeId(vertexGId.nodeId)!; + if (nodeId.equals(this.keyManager.getNodeId())) { + const vertexChainDataEncoded = + await this.sigchain.getChainData(); + // Decode all our claims - no need to verify (on our own sigChain) + for (const c in vertexChainDataEncoded) { + const claimId = c as ClaimIdEncoded; + vertexChainData[claimId] = claimsUtils.decodeClaim( + vertexChainDataEncoded[claimId], + ); + } + // Otherwise, request the verified chain data from the node + } else { + try { + vertexChainData = await this.nodeManager.requestChainData( + nodeId, + ); + } catch (e) { + this.visitedVertices.add(vertex); + await this.removeKeyFromDiscoveryQueue(vertexId); + this.logger.error( + `Failed to discover ${vertexGId.nodeId} - ${e.toString()}`, + ); + continue; + } } - // Otherwise, request the verified chain data from the node - } else { - try { - vertexChainData = await this.nodeManager.requestChainData( - nodeId, - ); - } catch (e) { - this.visitedVertices.add(vertex); - await this.removeKeyFromDiscoveryQueue(vertexId); - this.logger.error( - `Failed to discover ${vertexGId.nodeId} - ${e.toString()}`, - ); - yield; - continue; + // TODO: for now, the chain data is treated as a 'disjoint' set of + // cryptolink claims from a node to another node/identity + // That is, we have no notion of revocations, or multiple claims to the + // same node/identity. Thus, we simply iterate over this chain of + // cryptolinks. + // Now have the NodeInfo of this vertex + const vertexNodeInfo: NodeInfo = { + id: nodesUtils.encodeNodeId(nodeId), + chain: vertexChainData, + }; + // Iterate over each of the claims in the chain (already verified) + // TODO: because we're iterating over keys in a record, I don't believe + // that this will iterate in lexicographical order of keys. For now, + // this doesn't matter though (because of the previous comment). + for (const claimId in vertexChainData) { + const claim: Claim = vertexChainData[claimId as ClaimIdEncoded]; + // If the claim is to a node + if (claim.payload.data.type === 'node') { + // Get the chain data of the linked node + // Could be node1 or node2 in the claim so get the one that's + // not equal to nodeId from above + const node1Id = nodesUtils.decodeNodeId( + claim.payload.data.node1, + )!; + const node2Id = nodesUtils.decodeNodeId( + claim.payload.data.node2, + )!; + const linkedVertexNodeId = node1Id.equals(nodeId) + ? node2Id + : node1Id; + const linkedVertexGK = + gestaltsUtils.keyFromNode(linkedVertexNodeId); + let linkedVertexChainData: ChainData; + try { + linkedVertexChainData = + await this.nodeManager.requestChainData( + linkedVertexNodeId, + ); + } catch (e) { + if ( + e instanceof nodesErrors.ErrorNodeConnectionDestroyed || + e instanceof nodesErrors.ErrorNodeConnectionTimeout + ) { + if (!this.visitedVertices.has(linkedVertexGK)) { + await this.pushKeyToDiscoveryQueue(linkedVertexGK); + } + this.logger.error( + `Failed to discover ${nodesUtils.encodeNodeId( + linkedVertexNodeId, + )} - ${e.toString()}`, + ); + continue; + } else { + throw e; + } + } + // With this verified chain, we can link + const linkedVertexNodeInfo: NodeInfo = { + id: nodesUtils.encodeNodeId(linkedVertexNodeId), + chain: linkedVertexChainData, + }; + await this.gestaltGraph.linkNodeAndNode( + vertexNodeInfo, + linkedVertexNodeInfo, + ); + // Add this vertex to the queue if it hasn't already been visited + if (!this.visitedVertices.has(linkedVertexGK)) { + await this.pushKeyToDiscoveryQueue(linkedVertexGK); + } + } + // Else the claim is to an identity + if (claim.payload.data.type === 'identity') { + // Attempt to get the identity info on the identity provider + const identityInfo = await this.getIdentityInfo( + claim.payload.data.provider, + claim.payload.data.identity, + ); + // If we can't get identity info, simply skip this claim + if (identityInfo == null) { + continue; + } + // Link the node to the found identity info + await this.gestaltGraph.linkNodeAndIdentity( + vertexNodeInfo, + identityInfo, + ); + // Add this identity vertex to the queue if it is not present + const linkedIdentityGK = gestaltsUtils.keyFromIdentity( + claim.payload.data.provider, + claim.payload.data.identity, + ); + if (!this.visitedVertices.has(linkedIdentityGK)) { + await this.pushKeyToDiscoveryQueue(linkedIdentityGK); + } + } } } - // TODO: for now, the chain data is treated as a 'disjoint' set of - // cryptolink claims from a node to another node/identity - // That is, we have no notion of revocations, or multiple claims to the - // same node/identity. Thus, we simply iterate over this chain of - // cryptolinks. - // Now have the NodeInfo of this vertex - const vertexNodeInfo: NodeInfo = { - id: nodesUtils.encodeNodeId(nodeId), - chain: vertexChainData, - }; - // Iterate over each of the claims in the chain (already verified) - // TODO: because we're iterating over keys in a record, I don't believe - // that this will iterate in lexicographical order of keys. For now, - // this doesn't matter though (because of the previous comment). - for (const claimId in vertexChainData) { - const claim: Claim = vertexChainData[claimId as ClaimIdEncoded]; - // If the claim is to a node - if (claim.payload.data.type === 'node') { - // Get the chain data of the linked node - // Could be node1 or node2 in the claim so get the one that's - // not equal to nodeId from above - const node1Id = nodesUtils.decodeNodeId( - claim.payload.data.node1, - )!; - const node2Id = nodesUtils.decodeNodeId( - claim.payload.data.node2, - )!; - const linkedVertexNodeId = node1Id.equals(nodeId) - ? node2Id - : node1Id; + break; + case 'identity': + { + // If the next vertex is an identity, perform a social discovery + // Firstly get the identity info of this identity + const vertexIdentityInfo = await this.getIdentityInfo( + vertexGId.providerId, + vertexGId.identityId, + ); + // If we don't have identity info, simply skip this vertex + if (vertexIdentityInfo == null) { + continue; + } + // Link the identity with each node from its claims on the provider + // Iterate over each of the claims + for (const id in vertexIdentityInfo.claims) { + const identityClaimId = id as IdentityClaimId; + const claim = vertexIdentityInfo.claims[identityClaimId]; + // Claims on an identity provider will always be node -> identity + // So just cast payload data as such + const data = claim.payload.data as ClaimLinkIdentity; + const linkedVertexNodeId = nodesUtils.decodeNodeId(data.node)!; const linkedVertexGK = gestaltsUtils.keyFromNode(linkedVertexNodeId); + // Get the chain data of this claimed node (so that we can link in GG) let linkedVertexChainData: ChainData; try { linkedVertexChainData = @@ -290,11 +377,8 @@ class Discovery { await this.pushKeyToDiscoveryQueue(linkedVertexGK); } this.logger.error( - `Failed to discover ${nodesUtils.encodeNodeId( - linkedVertexNodeId, - )} - ${e.toString()}`, + `Failed to discover ${data.node} - ${e.toString()}`, ); - yield; continue; } else { throw e; @@ -305,126 +389,31 @@ class Discovery { id: nodesUtils.encodeNodeId(linkedVertexNodeId), chain: linkedVertexChainData, }; - await this.gestaltGraph.linkNodeAndNode( - vertexNodeInfo, + await this.gestaltGraph.linkNodeAndIdentity( linkedVertexNodeInfo, + vertexIdentityInfo, ); - // Add this vertex to the queue if it hasn't already been visited + // Add this vertex to the queue if it is not present if (!this.visitedVertices.has(linkedVertexGK)) { await this.pushKeyToDiscoveryQueue(linkedVertexGK); } } - // Else the claim is to an identity - if (claim.payload.data.type === 'identity') { - // Attempt to get the identity info on the identity provider - const identityInfo = await this.getIdentityInfo( - claim.payload.data.provider, - claim.payload.data.identity, - ); - // If we can't get identity info, simply skip this claim - if (identityInfo == null) { - continue; - } - // Link the node to the found identity info - await this.gestaltGraph.linkNodeAndIdentity( - vertexNodeInfo, - identityInfo, - ); - // Add this identity vertex to the queue if it is not present - const linkedIdentityGK = gestaltsUtils.keyFromIdentity( - claim.payload.data.provider, - claim.payload.data.identity, - ); - if (!this.visitedVertices.has(linkedIdentityGK)) { - await this.pushKeyToDiscoveryQueue(linkedIdentityGK); - } - } - } - } else if (vertexGId.type === 'identity') { - // If the next vertex is an identity, perform a social discovery - // Firstly get the identity info of this identity - const vertexIdentityInfo = await this.getIdentityInfo( - vertexGId.providerId, - vertexGId.identityId, - ); - // If we don't have identity info, simply skip this vertex - if (vertexIdentityInfo == null) { - continue; - } - // Link the identity with each node from its claims on the provider - // Iterate over each of the claims - for (const id in vertexIdentityInfo.claims) { - const identityClaimId = id as IdentityClaimId; - const claim = vertexIdentityInfo.claims[identityClaimId]; - // Claims on an identity provider will always be node -> identity - // So just cast payload data as such - const data = claim.payload.data as ClaimLinkIdentity; - const linkedVertexNodeId = nodesUtils.decodeNodeId(data.node)!; - const linkedVertexGK = - gestaltsUtils.keyFromNode(linkedVertexNodeId); - // Get the chain data of this claimed node (so that we can link in GG) - let linkedVertexChainData: ChainData; - try { - linkedVertexChainData = await this.nodeManager.requestChainData( - linkedVertexNodeId, - ); - } catch (e) { - if ( - e instanceof nodesErrors.ErrorNodeConnectionDestroyed || - e instanceof nodesErrors.ErrorNodeConnectionTimeout - ) { - if (!this.visitedVertices.has(linkedVertexGK)) { - await this.pushKeyToDiscoveryQueue(linkedVertexGK); - } - yield; - this.logger.error( - `Failed to discover ${data.node} - ${e.toString()}`, - ); - continue; - } else { - throw e; - } - } - // With this verified chain, we can link - const linkedVertexNodeInfo: NodeInfo = { - id: nodesUtils.encodeNodeId(linkedVertexNodeId), - chain: linkedVertexChainData, - }; - await this.gestaltGraph.linkNodeAndIdentity( - linkedVertexNodeInfo, - vertexIdentityInfo, - ); - // Add this vertex to the queue if it is not present - if (!this.visitedVertices.has(linkedVertexGK)) { - await this.pushKeyToDiscoveryQueue(linkedVertexGK); - } } - } - this.visitedVertices.add(vertex); - await this.removeKeyFromDiscoveryQueue(vertexId); - yield; - } - } else { - if (!(this[status] === 'stopping')) { - this.queuePlugRelease = await this.queuePlug.acquire(); + break; + default: + never(); } - await this.queuePlug.waitForUnlock(); - } - if (this[status] === 'stopping') { - break; + this.visitedVertices.add(vertex); + await this.removeKeyFromDiscoveryQueue(vertexId); } } } /** - * Used for iterating over the discovery queue. This method should run - * continuously whenever the Discovery module is started and should be exited - * only during stopping. + * Will resolve once the queue has drained */ - protected async runDiscoveryQueue() { - for await (const _ of this.discoveryQueue) { - // Empty - } + public async waitForDrained(): Promise { + await this.queueDrained.p; } /** @@ -432,18 +421,16 @@ class Discovery { * transaction lock to ensure consistency. */ protected async queueIsEmpty(): Promise { - return await utils.withF([this.transaction], async () => { + return await this.lock.withF(async () => { let nextDiscoveryQueueId: DiscoveryQueueId | undefined; - const keyStream = this.discoveryQueueDb.createKeyStream({ - limit: 1, - }); - for await (const o of keyStream) { - nextDiscoveryQueueId = IdInternal.fromBuffer(o); - } - if (nextDiscoveryQueueId == null) { - return true; + const keyIterator = this.db.iterator( + { limit: 1 }, + this.discoveryQueueDbPath, + ); + for await (const [key] of keyIterator) { + nextDiscoveryQueueId = IdInternal.fromBuffer(key); } - return false; + return nextDiscoveryQueueId == null; }); } @@ -452,25 +439,26 @@ class Discovery { * the queue if it was previously locked (due to being empty) * Will only add the Key if it does not already exist in the queue */ - protected async pushKeyToDiscoveryQueue(gk: GestaltKey) { - await utils.withF([this.transaction], async () => { - const valueStream = this.discoveryQueueDb.createValueStream({}); - for await (const key of valueStream) { - if (key === gk) { - return; + protected async pushKeyToDiscoveryQueue( + gestaltKey: GestaltKey, + ): Promise { + await resources.withF( + [this.db.transaction(), this.lock.lock()], + async ([tran]) => { + const valueIterator = tran.iterator({}, this.discoveryQueueDbPath); + for await (const [, value] of valueIterator) { + if (value.toString() === gestaltKey) { + return; + } } - } - const discoveryQueueId = this.discoveryQueueIdGenerator(); - await this.db.put( - this.discoveryQueueDbDomain, - idUtils.toBuffer(discoveryQueueId), - gk, - ); - }); - if (this.queuePlugRelease != null) { - this.queuePlugRelease(); - this.queuePlugRelease = undefined; - } + const discoveryQueueId = this.discoveryQueueIdGenerator(); + await tran.put( + [...this.discoveryQueueDbPath, idUtils.toBuffer(discoveryQueueId)], + gestaltKey, + ); + }, + ); + this.queuePlug.resolveP(); } /** @@ -478,9 +466,14 @@ class Discovery { * only be done after a Key has been discovered in order to remove it from * the beginning of the queue. */ - protected async removeKeyFromDiscoveryQueue(keyId: DiscoveryQueueId) { - await utils.withF([this.transaction], async () => { - await this.db.del(this.discoveryQueueDbDomain, idUtils.toBuffer(keyId)); + protected async removeKeyFromDiscoveryQueue( + keyId: DiscoveryQueueId, + ): Promise { + await this.lock.withF(async () => { + await this.db.del([ + ...this.discoveryQueueDbPath, + idUtils.toBuffer(keyId), + ]); }); } diff --git a/src/discovery/errors.ts b/src/discovery/errors.ts index cadf81048..ca83bfd18 100644 --- a/src/discovery/errors.ts +++ b/src/discovery/errors.ts @@ -1,12 +1,21 @@ -import { ErrorPolykey } from '../errors'; +import { ErrorPolykey, sysexits } from '../errors'; -class ErrorDiscovery extends ErrorPolykey {} +class ErrorDiscovery extends ErrorPolykey {} -class ErrorDiscoveryRunning extends ErrorDiscovery {} +class ErrorDiscoveryRunning extends ErrorDiscovery { + static description = 'Discovery is running'; + exitCode = sysexits.USAGE; +} -class ErrorDiscoveryDestroyed extends ErrorDiscovery {} +class ErrorDiscoveryDestroyed extends ErrorDiscovery { + static description = 'Discovery is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorDiscoveryNotRunning extends ErrorDiscovery {} +class ErrorDiscoveryNotRunning extends ErrorDiscovery { + static description = 'Discovery is not running'; + exitCode = sysexits.USAGE; +} export { ErrorDiscovery, diff --git a/src/errors.ts b/src/errors.ts index 1d224575e..53ec7b8ed 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,31 +1,61 @@ import ErrorPolykey from './ErrorPolykey'; import sysexits from './utils/sysexits'; -class ErrorPolykeyUnimplemented extends ErrorPolykey { - description = 'This is an unimplemented functionality'; +class ErrorPolykeyUnimplemented extends ErrorPolykey { + static description = 'This is an unimplemented functionality'; exitCode = sysexits.UNAVAILABLE; } -class ErrorPolykeyAgentRunning extends ErrorPolykey {} +class ErrorPolykeyUnknown extends ErrorPolykey { + static description = 'Unable to deserialise to known error'; + exitCode = sysexits.UNKNOWN; +} -class ErrorPolykeyAgentNotRunning extends ErrorPolykey {} +class ErrorPolykeyRemote extends ErrorPolykey { + static description = 'Remote error from RPC call'; + exitCode = sysexits.UNAVAILABLE; +} -class ErrorPolykeyAgentDestroyed extends ErrorPolykey {} +class ErrorPolykeyAgentRunning extends ErrorPolykey { + static description = 'PolykeyAgent is running'; + exitCode = sysexits.USAGE; +} -class ErrorPolykeyClientRunning extends ErrorPolykey {} +class ErrorPolykeyAgentNotRunning extends ErrorPolykey { + static description = 'PolykeyAgent is not running'; + exitCode = sysexits.USAGE; +} -class ErrorPolykeyClientNotRunning extends ErrorPolykey {} +class ErrorPolykeyAgentDestroyed extends ErrorPolykey { + static description = 'PolykeyAgent is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorPolykeyClientDestroyed extends ErrorPolykey {} +class ErrorPolykeyClientRunning extends ErrorPolykey { + static description = 'PolykeyClient is running'; + exitCode = sysexits.USAGE; +} + +class ErrorPolykeyClientNotRunning extends ErrorPolykey { + static description = 'PolykeyClient is not running'; + exitCode = sysexits.USAGE; +} + +class ErrorPolykeyClientDestroyed extends ErrorPolykey { + static description = 'PolykeyClient is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorInvalidId extends ErrorPolykey {} +class ErrorInvalidId extends ErrorPolykey {} -class ErrorInvalidConfigEnvironment extends ErrorPolykey {} +class ErrorInvalidConfigEnvironment extends ErrorPolykey {} export { sysexits, ErrorPolykey, ErrorPolykeyUnimplemented, + ErrorPolykeyUnknown, + ErrorPolykeyRemote, ErrorPolykeyAgentRunning, ErrorPolykeyAgentNotRunning, ErrorPolykeyAgentDestroyed, diff --git a/src/gestalts/GestaltGraph.ts b/src/gestalts/GestaltGraph.ts index 4e9036d7a..0cb613a31 100644 --- a/src/gestalts/GestaltGraph.ts +++ b/src/gestalts/GestaltGraph.ts @@ -1,4 +1,4 @@ -import type { DB, DBLevel, DBOp } from '@matrixai/db'; +import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { Gestalt, GestaltAction, @@ -10,14 +10,15 @@ import type { } from './types'; import type { NodeId, NodeInfo } from '../nodes/types'; import type { IdentityId, IdentityInfo, ProviderId } from '../identities/types'; -import type { ACL } from '../acl'; import type { Permission } from '../acl/types'; -import { Mutex } from 'async-mutex'; +import type ACL from '../acl/ACL'; import Logger from '@matrixai/logger'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; +import { utils as dbUtils } from '@matrixai/db'; +import { withF } from '@matrixai/resources'; import * as gestaltsUtils from './utils'; import * as gestaltsErrors from './errors'; import * as aclUtils from '../acl/utils'; @@ -30,22 +31,6 @@ interface GestaltGraph extends CreateDestroyStartStop {} new gestaltsErrors.ErrorGestaltsGraphDestroyed(), ) class GestaltGraph { - protected logger: Logger; - protected db: DB; - protected acl: ACL; - protected graphDbDomain: string = this.constructor.name; - protected graphMatrixDbDomain: Array = [this.graphDbDomain, 'matrix']; - protected graphNodesDbDomain: Array = [this.graphDbDomain, 'nodes']; - protected graphIdentitiesDbDomain: Array = [ - this.graphDbDomain, - 'identities', - ]; - protected graphDb: DBLevel; - protected graphMatrixDb: DBLevel; - protected graphNodesDb: DBLevel; - protected graphIdentitiesDb: DBLevel; - protected lock: Mutex = new Mutex(); - static async createGestaltGraph({ db, acl, @@ -64,38 +49,34 @@ class GestaltGraph { return gestaltGraph; } + protected logger: Logger; + protected db: DB; + protected acl: ACL; + protected gestaltGraphDbPath: LevelPath = [this.constructor.name]; + protected gestaltGraphMatrixDbPath: LevelPath = [ + this.constructor.name, + 'matrix', + ]; + protected gestaltGraphNodesDbPath: LevelPath = [ + this.constructor.name, + 'nodes', + ]; + protected gestaltGraphIdentitiesDbPath: LevelPath = [ + this.constructor.name, + 'identities', + ]; + constructor({ db, acl, logger }: { db: DB; acl: ACL; logger: Logger }) { this.logger = logger; this.db = db; this.acl = acl; } - get locked(): boolean { - return this.lock.isLocked(); - } - public async start({ fresh = false }: { fresh?: boolean } = {}) { this.logger.info(`Starting ${this.constructor.name}`); - const graphDb = await this.db.level(this.graphDbDomain); - const graphMatrixDb = await this.db.level( - this.graphMatrixDbDomain[1], - graphDb, - ); - const graphNodesDb = await this.db.level( - this.graphNodesDbDomain[1], - graphDb, - ); - const graphIdentitiesDb = await this.db.level( - this.graphIdentitiesDbDomain[1], - graphDb, - ); if (fresh) { - await graphDb.clear(); + await this.db.clear(this.gestaltGraphDbPath); } - this.graphDb = graphDb; - this.graphMatrixDb = graphMatrixDb; - this.graphNodesDb = graphNodesDb; - this.graphIdentitiesDb = graphIdentitiesDb; this.logger.info(`Started ${this.constructor.name}`); } @@ -106,200 +87,173 @@ class GestaltGraph { async destroy() { this.logger.info(`Destroying ${this.constructor.name}`); - const graphDb = await this.db.level(this.graphDbDomain); - await graphDb.clear(); + await this.db.clear(this.gestaltGraphDbPath); this.logger.info(`Destroyed ${this.constructor.name}`); } - /** - * Run several operations within the same lock - * This does not ensure atomicity of the underlying database - * Database atomicity still depends on the underlying operation - */ - public async transaction( - f: (gestaltGraph: GestaltGraph) => Promise, + @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) + public async withTransactionF( + f: (tran: DBTransaction) => Promise, ): Promise { - const release = await this.lock.acquire(); - try { - return await f(this); - } finally { - release(); - } - } - - /** - * Transaction wrapper that will not lock if the operation was executed - * within a transaction context - */ - public async _transaction(f: () => Promise): Promise { - if (this.lock.isLocked()) { - return await f(); - } else { - return await this.transaction(f); - } + return withF([this.db.transaction()], ([tran]) => f(tran)); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async getGestalts(): Promise> { - return await this._transaction(async () => { - const unvisited: Map = new Map(); - for await (const o of this.graphMatrixDb.createReadStream()) { - const gK = (o as any).key.toString() as GestaltKey; - const data = (o as any).value as Buffer; - const gKs = await this.db.deserializeDecrypt( - data, - false, - ); - unvisited.set(gK, gKs); - } - const gestalts: Array = []; - let gestalt: Gestalt; - for (const gKSet of unvisited) { - gestalt = { - matrix: {}, - nodes: {}, - identities: {}, - }; - const gK = gKSet[0]; - const queue = [gK]; - while (true) { - const vertex = queue.shift(); - if (vertex == null) { - gestalts.push(gestalt); - break; - } - const gId = gestaltsUtils.ungestaltKey(vertex); - const vertexKeys = unvisited.get(vertex); - if (vertexKeys == null) { - // This should not happen - break; - } - gestalt.matrix[vertex] = vertexKeys; - if (gId.type === 'node') { - const nodeInfo = await this.db.get( - this.graphNodesDbDomain, - vertex as GestaltNodeKey, - ); - gestalt.nodes[vertex] = nodeInfo!; - } else if (gId.type === 'identity') { - const identityInfo = await this.db.get( - this.graphIdentitiesDbDomain, - vertex as GestaltIdentityKey, - ); - gestalt.identities[vertex] = identityInfo!; - } - unvisited.delete(vertex); - const neighbours: Array = Object.keys(vertexKeys).filter( - (k: GestaltKey) => unvisited.has(k), - ) as Array; - queue.push(...neighbours); + public async getGestalts(tran?: DBTransaction): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => this.getGestalts(tran)); + } + const unvisited: Map = new Map(); + for await (const [k, v] of tran.iterator(undefined, [ + ...this.gestaltGraphMatrixDbPath, + ])) { + const gK = k.toString() as GestaltKey; + const gKs = dbUtils.deserialize(v); + unvisited.set(gK, gKs); + } + const gestalts: Array = []; + let gestalt: Gestalt; + for (const gKSet of unvisited) { + gestalt = { + matrix: {}, + nodes: {}, + identities: {}, + }; + const gK = gKSet[0]; + const queue = [gK]; + while (true) { + const vertex = queue.shift(); + if (vertex == null) { + gestalts.push(gestalt); + break; + } + const gId = gestaltsUtils.ungestaltKey(vertex); + const vertexKeys = unvisited.get(vertex); + if (vertexKeys == null) { + // This should not happen + break; } + gestalt.matrix[vertex] = vertexKeys; + if (gId.type === 'node') { + const vertexPath = [ + ...this.gestaltGraphNodesDbPath, + vertex as GestaltNodeKey, + ] as unknown as KeyPath; + const nodeInfo = await tran.get(vertexPath); + gestalt.nodes[vertex] = nodeInfo!; + } else if (gId.type === 'identity') { + const vertexPath = [ + ...this.gestaltGraphIdentitiesDbPath, + vertex as GestaltIdentityKey, + ] as unknown as KeyPath; + const identityInfo = await tran.get(vertexPath); + gestalt.identities[vertex] = identityInfo!; + } + unvisited.delete(vertex); + const neighbours: Array = Object.keys(vertexKeys).filter( + (k: GestaltKey) => unvisited.has(k), + ) as Array; + queue.push(...neighbours); } - return gestalts; - }); + } + return gestalts; } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async getGestaltByNode(nodeId: NodeId): Promise { + public async getGestaltByNode( + nodeId: NodeId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getGestaltByNode(nodeId, tran), + ); + } const nodeKey = gestaltsUtils.keyFromNode(nodeId); - return this.getGestaltByKey(nodeKey); + return this.getGestaltByKey(nodeKey, tran); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) public async getGestaltByIdentity( providerId: ProviderId, identityId: IdentityId, + tran?: DBTransaction, ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getGestaltByIdentity(providerId, identityId, tran), + ); + } const identityKey = gestaltsUtils.keyFromIdentity(providerId, identityId); - return this.getGestaltByKey(identityKey); + return this.getGestaltByKey(identityKey, tran); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async setIdentity(identityInfo: IdentityInfo): Promise { - return await this._transaction(async () => { - const ops = await this.setIdentityOps(identityInfo); - await this.db.batch(ops); - }); - } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async setIdentityOps( + public async setIdentity( identityInfo: IdentityInfo, - ): Promise> { + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setIdentity(identityInfo, tran), + ); + } const identityKey = gestaltsUtils.keyFromIdentity( identityInfo.providerId, identityInfo.identityId, ); + const identityKeyPath = [ + ...this.gestaltGraphMatrixDbPath, + identityKey, + ] as unknown as KeyPath; const identityKeyKeys = - (await this.db.get( - this.graphMatrixDbDomain, - identityKey, - )) ?? {}; - const ops: Array = [ - { - type: 'put', - domain: this.graphMatrixDbDomain, - key: identityKey, - value: identityKeyKeys, - }, - { - type: 'put', - domain: this.graphIdentitiesDbDomain, - key: identityKey, - value: identityInfo, - }, - ]; - return ops; - } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async unsetIdentity(providerId: ProviderId, identityId: IdentityId) { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const ops = await this.unsetIdentityOps(providerId, identityId); - await this.db.batch(ops); - }); - }); + (await tran.get(identityKeyPath)) ?? {}; + await tran.put(identityKeyPath, identityKeyKeys); + const identityInfoPath = [ + ...this.gestaltGraphIdentitiesDbPath, + identityKey, + ] as unknown as KeyPath; + await tran.put(identityInfoPath, identityInfo); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async unsetIdentityOps( + public async unsetIdentity( providerId: ProviderId, identityId: IdentityId, + tran?: DBTransaction, ) { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetIdentity(providerId, identityId, tran), + ); + } const identityKey = gestaltsUtils.keyFromIdentity(providerId, identityId); - const identityKeyKeys = await this.db.get( - this.graphMatrixDbDomain, + const identityKeyPath = [ + ...this.gestaltGraphMatrixDbPath, identityKey, - ); - const ops: Array = []; + ] as unknown as KeyPath; + const identityKeyKeys = await tran.get(identityKeyPath); if (identityKeyKeys == null) { - return ops; + return; } - ops.push({ - type: 'del', - domain: this.graphIdentitiesDbDomain, - key: identityKey, - }); + const identityPath = [ + ...this.gestaltGraphIdentitiesDbPath, + identityKey, + ] as unknown as KeyPath; + await tran.del(identityPath); for (const key of Object.keys(identityKeyKeys) as Array) { const gId = gestaltsUtils.ungestaltKey(key); if (gId.type === 'node') { - ops.push( - ...(await this.unlinkNodeAndIdentityOps( - nodesUtils.decodeNodeId(gId.nodeId)!, - providerId, - identityId, - )), + await this.unlinkNodeAndIdentity( + nodesUtils.decodeNodeId(gId.nodeId)!, + providerId, + identityId, + tran, ); } } // Ensure that an empty key set is still deleted - ops.push({ - type: 'del', - domain: this.graphMatrixDbDomain, - key: identityKey, - }); - return ops; + await tran.del(identityKeyPath); } /** @@ -309,53 +263,41 @@ class GestaltGraph { * to a new gestalt permission in the acl */ @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async setNode(nodeInfo: NodeInfo): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const ops = await this.setNodeOps(nodeInfo); - await this.db.batch(ops); - }); - }); - } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async setNodeOps(nodeInfo: NodeInfo): Promise> { + public async setNode( + nodeInfo: NodeInfo, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setNode(nodeInfo, tran), + ); + } const nodeKey = gestaltsUtils.keyFromNode( nodesUtils.decodeNodeId(nodeInfo.id)!, ); - const ops: Array = []; - let nodeKeyKeys = await this.db.get( - this.graphMatrixDbDomain, + const nodeKeyPath = [ + ...this.gestaltGraphMatrixDbPath, nodeKey, - ); + ] as unknown as KeyPath; + let nodeKeyKeys = await tran.get(nodeKeyPath); if (nodeKeyKeys == null) { nodeKeyKeys = {}; // Sets the gestalt in the acl - ops.push( - ...(await this.acl.setNodePermOps( - nodesUtils.decodeNodeId(nodeInfo.id)!, - { - gestalt: {}, - vaults: {}, - }, - )), + await this.acl.setNodePerm( + nodesUtils.decodeNodeId(nodeInfo.id)!, + { + gestalt: {}, + vaults: {}, + }, + tran, ); } - ops.push( - { - type: 'put', - domain: this.graphMatrixDbDomain, - key: nodeKey, - value: nodeKeyKeys, - }, - { - type: 'put', - domain: this.graphNodesDbDomain, - key: nodeKey, - value: nodeInfo, - }, - ); - return ops; + await tran.put(nodeKeyPath, nodeKeyKeys); + const nodePath = [ + ...this.gestaltGraphNodesDbPath, + nodeKey, + ] as unknown as KeyPath; + await tran.put(nodePath, nodeInfo); } /** @@ -364,81 +306,61 @@ class GestaltGraph { * to the gestalt permission in the acl */ @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async unsetNode(nodeId: NodeId): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const ops = await this.unsetNodeOps(nodeId); - await this.db.batch(ops); - }); - }); - } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async unsetNodeOps(nodeId: NodeId): Promise> { + public async unsetNode(nodeId: NodeId, tran?: DBTransaction): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetNode(nodeId, tran), + ); + } const nodeKey = gestaltsUtils.keyFromNode(nodeId); - const nodeKeyKeys = await this.db.get( - this.graphMatrixDbDomain, + const nodeKeyPath = [ + ...this.gestaltGraphMatrixDbPath, nodeKey, - ); - const ops: Array = []; + ] as unknown as KeyPath; + const nodeKeyKeys = await tran.get(nodeKeyPath); if (nodeKeyKeys == null) { - return ops; + return; } - ops.push({ - type: 'del', - domain: this.graphNodesDbDomain, - key: nodeKey, - }); + const nodePath = [ + ...this.gestaltGraphNodesDbPath, + nodeKey, + ] as unknown as KeyPath; + await tran.del(nodePath); for (const key of Object.keys(nodeKeyKeys) as Array) { const gId = gestaltsUtils.ungestaltKey(key); if (gId.type === 'node') { - ops.push( - ...(await this.unlinkNodeAndNodeOps( - nodeId, - nodesUtils.decodeNodeId(gId.nodeId)!, - )), + await this.unlinkNodeAndNode( + nodeId, + nodesUtils.decodeNodeId(gId.nodeId)!, + tran, ); } else if (gId.type === 'identity') { - ops.push( - ...(await this.unlinkNodeAndIdentityOps( - nodeId, - gId.providerId, - gId.identityId, - )), + await this.unlinkNodeAndIdentity( + nodeId, + gId.providerId, + gId.identityId, + tran, ); } } // Ensure that an empty key set is still deleted - ops.push({ - type: 'del', - domain: this.graphMatrixDbDomain, - key: nodeKey, - }); + await tran.del(nodeKeyPath); // Unsets the gestalt in the acl // this must be done after all unlinking operations - ops.push(...(await this.acl.unsetNodePermOps(nodeId))); - return ops; + await this.acl.unsetNodePerm(nodeId, tran); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) public async linkNodeAndIdentity( nodeInfo: NodeInfo, identityInfo: IdentityInfo, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const ops = await this.linkNodeAndIdentityOps(nodeInfo, identityInfo); - await this.db.batch(ops); - }); - }); - } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async linkNodeAndIdentityOps( - nodeInfo: NodeInfo, - identityInfo: IdentityInfo, - ): Promise> { - const ops: Array = []; + if (tran == null) { + return this.withTransactionF(async (tran) => + this.linkNodeAndIdentity(nodeInfo, identityInfo, tran), + ); + } const nodeKey = gestaltsUtils.keyFromNode( nodesUtils.decodeNodeId(nodeInfo.id)!, ); @@ -446,14 +368,16 @@ class GestaltGraph { identityInfo.providerId, identityInfo.identityId, ); - let nodeKeyKeys = await this.db.get( - this.graphMatrixDbDomain, + const nodeKeyPath = [ + ...this.gestaltGraphMatrixDbPath, nodeKey, - ); - let identityKeyKeys = await this.db.get( - this.graphMatrixDbDomain, + ] as unknown as KeyPath; + const identityKeyPath = [ + ...this.gestaltGraphMatrixDbPath, identityKey, - ); + ] as unknown as KeyPath; + let nodeKeyKeys = await tran.get(nodeKeyPath); + let identityKeyKeys = await tran.get(identityKeyPath); // If they are already connected we do nothing if ( nodeKeyKeys && @@ -461,7 +385,7 @@ class GestaltGraph { identityKeyKeys && nodeKey in identityKeyKeys ) { - return ops; + return; } let nodeNew = false; if (nodeKeyKeys == null) { @@ -490,14 +414,13 @@ class GestaltGraph { // else // join node gestalt's permission to the identity gestalt if (nodeNew && identityNew) { - ops.push( - ...(await this.acl.setNodePermOps( - nodesUtils.decodeNodeId(nodeInfo.id)!, - { - gestalt: {}, - vaults: {}, - }, - )), + await this.acl.setNodePerm( + nodesUtils.decodeNodeId(nodeInfo.id)!, + { + gestalt: {}, + vaults: {}, + }, + tran, ); } else if ( !nodeNew && @@ -507,6 +430,7 @@ class GestaltGraph { const [, identityNodeKeys] = await this.traverseGestalt( Object.keys(identityKeyKeys) as Array, [identityKey], + tran, ); const identityNodeIds = Array.from(identityNodeKeys, (key) => gestaltsUtils.nodeFromKey(key), @@ -514,32 +438,32 @@ class GestaltGraph { // These must exist const nodePerm = (await this.acl.getNodePerm( nodesUtils.decodeNodeId(nodeInfo.id)!, + tran, )) as Permission; const identityPerm = (await this.acl.getNodePerm( identityNodeIds[0], + tran, )) as Permission; // Union the perms together const permNew = aclUtils.permUnion(nodePerm, identityPerm); // Node perm is updated and identity perm is joined to node perm // this has to be done as 1 call to acl in order to combine ref count update // and the perm record update - ops.push( - ...(await this.acl.joinNodePermOps( - nodesUtils.decodeNodeId(nodeInfo.id)!, - identityNodeIds, - permNew, - )), + await this.acl.joinNodePerm( + nodesUtils.decodeNodeId(nodeInfo.id)!, + identityNodeIds, + permNew, + tran, ); } else if (nodeNew && !identityNew) { if (utils.isEmptyObject(identityKeyKeys)) { - ops.push( - ...(await this.acl.setNodePermOps( - nodesUtils.decodeNodeId(nodeInfo.id)!, - { - gestalt: {}, - vaults: {}, - }, - )), + await this.acl.setNodePerm( + nodesUtils.decodeNodeId(nodeInfo.id)!, + { + gestalt: {}, + vaults: {}, + }, + tran, ); } else { let identityNodeKey: GestaltNodeKey; @@ -548,75 +472,55 @@ class GestaltGraph { break; } const identityNodeId = gestaltsUtils.nodeFromKey(identityNodeKey!); - ops.push( - ...(await this.acl.joinNodePermOps(identityNodeId, [ - nodesUtils.decodeNodeId(nodeInfo.id)!, - ])), + await this.acl.joinNodePerm( + identityNodeId, + [nodesUtils.decodeNodeId(nodeInfo.id)!], + undefined, + tran, ); } } nodeKeyKeys[identityKey] = null; identityKeyKeys[nodeKey] = null; - ops.push( - { - type: 'put', - domain: this.graphMatrixDbDomain, - key: nodeKey, - value: nodeKeyKeys, - }, - { - type: 'put', - domain: this.graphMatrixDbDomain, - key: identityKey, - value: identityKeyKeys, - }, - { - type: 'put', - domain: this.graphNodesDbDomain, - key: nodeKey, - value: nodeInfo, - }, - { - type: 'put', - domain: this.graphIdentitiesDbDomain, - key: identityKey, - value: identityInfo, - }, - ); - return ops; + await tran.put(nodeKeyPath, nodeKeyKeys); + await tran.put(identityKeyPath, identityKeyKeys); + const nodePath = [ + ...this.gestaltGraphNodesDbPath, + nodeKey, + ] as unknown as KeyPath; + await tran.put(nodePath, nodeInfo); + const identityPath = [ + ...this.gestaltGraphIdentitiesDbPath, + identityKey, + ] as unknown as KeyPath; + await tran.put(identityPath, identityInfo); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) public async linkNodeAndNode( nodeInfo1: NodeInfo, nodeInfo2: NodeInfo, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const ops = await this.linkNodeAndNodeOps(nodeInfo1, nodeInfo2); - await this.db.batch(ops); - }); - }); - } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async linkNodeAndNodeOps( - nodeInfo1: NodeInfo, - nodeInfo2: NodeInfo, - ): Promise> { - const ops: Array = []; + if (tran == null) { + return this.withTransactionF(async (tran) => + this.linkNodeAndNode(nodeInfo1, nodeInfo2, tran), + ); + } const nodeIdEncoded1 = nodesUtils.decodeNodeId(nodeInfo1.id)!; const nodeIdEncoded2 = nodesUtils.decodeNodeId(nodeInfo2.id)!; const nodeKey1 = gestaltsUtils.keyFromNode(nodeIdEncoded1); const nodeKey2 = gestaltsUtils.keyFromNode(nodeIdEncoded2); - let nodeKeyKeys1 = await this.db.get( - this.graphMatrixDbDomain, + const nodeKey1Path = [ + ...this.gestaltGraphMatrixDbPath, nodeKey1, - ); - let nodeKeyKeys2 = await this.db.get( - this.graphMatrixDbDomain, + ] as unknown as KeyPath; + const nodeKey2Path = [ + ...this.gestaltGraphMatrixDbPath, nodeKey2, - ); + ] as unknown as KeyPath; + let nodeKeyKeys1 = await tran.get(nodeKey1Path); + let nodeKeyKeys2 = await tran.get(nodeKey2Path); // If they are already connected we do nothing if ( nodeKeyKeys1 && @@ -624,7 +528,7 @@ class GestaltGraph { nodeKeyKeys2 && nodeKey1 in nodeKeyKeys2 ) { - return ops; + return; } let nodeNew1 = false; if (nodeKeyKeys1 == null) { @@ -647,16 +551,19 @@ class GestaltGraph { // if node 1 is new but node 2 exists // join node 1 gestalt's permission to the node 2 gestalt if (nodeNew1 && nodeNew2) { - ops.push( - ...(await this.acl.setNodesPermOps([nodeIdEncoded1, nodeIdEncoded2], { + await this.acl.setNodesPerm( + [nodeIdEncoded1, nodeIdEncoded2], + { gestalt: {}, vaults: {}, - })), + }, + tran, ); } else if (!nodeNew1 && !nodeNew2) { const [, nodeNodeKeys2] = await this.traverseGestalt( Object.keys(nodeKeyKeys2) as Array, [nodeKey2], + tran, ); const nodeNodeIds2 = Array.from(nodeNodeKeys2, (key) => gestaltsUtils.nodeFromKey(key), @@ -664,60 +571,47 @@ class GestaltGraph { // These must exist const nodePerm1 = (await this.acl.getNodePerm( nodeIdEncoded1, + tran, )) as Permission; const nodePerm2 = (await this.acl.getNodePerm( nodeIdEncoded2, + tran, )) as Permission; // Union the perms together const permNew = aclUtils.permUnion(nodePerm1, nodePerm2); // Node perm 1 is updated and node perm 2 is joined to node perm 2 // this has to be done as 1 call to acl in order to combine ref count update // and the perm record update - ops.push( - ...(await this.acl.joinNodePermOps( - nodeIdEncoded1, - nodeNodeIds2, - permNew, - )), - ); + await this.acl.joinNodePerm(nodeIdEncoded1, nodeNodeIds2, permNew, tran); } else if (nodeNew1 && !nodeNew2) { - ops.push( - ...(await this.acl.joinNodePermOps(nodeIdEncoded2, [nodeIdEncoded1])), + await this.acl.joinNodePerm( + nodeIdEncoded2, + [nodeIdEncoded1], + undefined, + tran, ); } else if (!nodeNew1 && nodeNew2) { - ops.push( - ...(await this.acl.joinNodePermOps(nodeIdEncoded1, [nodeIdEncoded2])), + await this.acl.joinNodePerm( + nodeIdEncoded1, + [nodeIdEncoded2], + undefined, + tran, ); } nodeKeyKeys1[nodeKey2] = null; nodeKeyKeys2[nodeKey1] = null; - ops.push( - { - type: 'put', - domain: this.graphMatrixDbDomain, - key: nodeKey1, - value: nodeKeyKeys1, - }, - { - type: 'put', - domain: this.graphMatrixDbDomain, - key: nodeKey2, - value: nodeKeyKeys2, - }, - { - type: 'put', - domain: this.graphNodesDbDomain, - key: nodeKey1, - value: nodeInfo1, - }, - { - type: 'put', - domain: this.graphNodesDbDomain, - key: nodeKey2, - value: nodeInfo2, - }, - ); - return ops; + await tran.put(nodeKey1Path, nodeKeyKeys1); + await tran.put(nodeKey2Path, nodeKeyKeys2); + const node1Path = [ + ...this.gestaltGraphNodesDbPath, + nodeKey1, + ] as unknown as KeyPath; + await tran.put(node1Path, nodeInfo1); + const node2Path = [ + ...this.gestaltGraphNodesDbPath, + nodeKey2, + ] as unknown as KeyPath; + await tran.put(node2Path, nodeInfo2); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) @@ -725,56 +619,35 @@ class GestaltGraph { nodeId: NodeId, providerId: ProviderId, identityId: IdentityId, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const ops = await this.unlinkNodeAndIdentityOps( - nodeId, - providerId, - identityId, - ); - await this.db.batch(ops); - }); - }); - } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async unlinkNodeAndIdentityOps( - nodeId: NodeId, - providerId: ProviderId, - identityId: IdentityId, - ): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unlinkNodeAndIdentity(nodeId, providerId, identityId, tran), + ); + } const nodeKey = gestaltsUtils.keyFromNode(nodeId); const identityKey = gestaltsUtils.keyFromIdentity(providerId, identityId); - const nodeKeyKeys = await this.db.get( - this.graphMatrixDbDomain, + const nodeKeyPath = [ + ...this.gestaltGraphMatrixDbPath, nodeKey, - ); - const identityKeyKeys = await this.db.get( - this.graphMatrixDbDomain, + ] as unknown as KeyPath; + const identityKeyPath = [ + ...this.gestaltGraphMatrixDbPath, identityKey, - ); + ] as unknown as KeyPath; + const nodeKeyKeys = await tran.get(nodeKeyPath); + const identityKeyKeys = await tran.get(identityKeyPath); let unlinking = false; - const ops: Array = []; if (nodeKeyKeys && identityKey in nodeKeyKeys) { unlinking = true; delete nodeKeyKeys[identityKey]; - ops.push({ - type: 'put', - domain: this.graphMatrixDbDomain, - key: nodeKey, - value: nodeKeyKeys, - }); + await tran.put(nodeKeyPath, nodeKeyKeys); } if (identityKeyKeys && nodeKey in identityKeyKeys) { unlinking = true; delete identityKeyKeys[nodeKey]; - ops.push({ - type: 'put', - domain: this.graphMatrixDbDomain, - key: identityKey, - value: identityKeyKeys, - }); + await tran.put(identityKeyPath, identityKeyKeys); } if (nodeKeyKeys && identityKeyKeys && unlinking) { // Check if the gestalts have split @@ -783,69 +656,53 @@ class GestaltGraph { await this.traverseGestalt( Object.keys(nodeKeyKeys) as Array, [nodeKey], + tran, ); if (!gestaltIdentityKeys.has(identityKey)) { const nodeIds = Array.from(gestaltNodeKeys, (key) => gestaltsUtils.nodeFromKey(key), ); // It is assumed that an existing gestalt has a permission - const perm = (await this.acl.getNodePerm(nodeId)) as Permission; + const perm = (await this.acl.getNodePerm(nodeId, tran)) as Permission; // This remaps all existing nodes to a new permission - ops.push(...(await this.acl.setNodesPermOps(nodeIds, perm))); + await this.acl.setNodesPerm(nodeIds, perm, tran); } } - return ops; } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) public async unlinkNodeAndNode( nodeId1: NodeId, nodeId2: NodeId, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const ops = await this.unlinkNodeAndNodeOps(nodeId1, nodeId2); - await this.db.batch(ops); - }); - }); - } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async unlinkNodeAndNodeOps( - nodeId1: NodeId, - nodeId2: NodeId, - ): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unlinkNodeAndNode(nodeId1, nodeId2, tran), + ); + } const nodeKey1 = gestaltsUtils.keyFromNode(nodeId1); const nodeKey2 = gestaltsUtils.keyFromNode(nodeId2); - const nodeKeyKeys1 = await this.db.get( - this.graphMatrixDbDomain, + const nodeKey1Path = [ + ...this.gestaltGraphMatrixDbPath, nodeKey1, - ); - const nodeKeyKeys2 = await this.db.get( - this.graphMatrixDbDomain, + ] as unknown as KeyPath; + const nodeKey2Path = [ + ...this.gestaltGraphMatrixDbPath, nodeKey2, - ); + ] as unknown as KeyPath; + const nodeKeyKeys1 = await tran.get(nodeKey1Path); + const nodeKeyKeys2 = await tran.get(nodeKey2Path); let unlinking = false; - const ops: Array = []; if (nodeKeyKeys1 && nodeKey2 in nodeKeyKeys1) { unlinking = true; delete nodeKeyKeys1[nodeKey2]; - ops.push({ - type: 'put', - domain: this.graphMatrixDbDomain, - key: nodeKey1, - value: nodeKeyKeys1, - }); + await tran.put(nodeKey1Path, nodeKeyKeys1); } if (nodeKeyKeys2 && nodeKey1 in nodeKeyKeys2) { unlinking = true; delete nodeKeyKeys2[nodeKey1]; - ops.push({ - type: 'put', - domain: this.graphMatrixDbDomain, - key: nodeKey2, - value: nodeKeyKeys2, - }); + await tran.put(nodeKey2Path, nodeKeyKeys2); } if (nodeKeyKeys1 && nodeKeyKeys2 && unlinking) { // Check if the gestalts have split @@ -853,99 +710,106 @@ class GestaltGraph { const [, gestaltNodeKeys] = await this.traverseGestalt( Object.keys(nodeKeyKeys1) as Array, [nodeKey1], + tran, ); if (!gestaltNodeKeys.has(nodeKey2)) { const nodeIds = Array.from(gestaltNodeKeys, (key) => gestaltsUtils.nodeFromKey(key), ); // It is assumed that an existing gestalt has a permission - const perm = (await this.acl.getNodePerm(nodeId1)) as Permission; + const perm = (await this.acl.getNodePerm(nodeId1, tran)) as Permission; // This remaps all existing nodes to a new permission - ops.push(...(await this.acl.setNodesPermOps(nodeIds, perm))); + await this.acl.setNodesPerm(nodeIds, perm, tran); } } - return ops; } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) public async getGestaltActionsByNode( nodeId: NodeId, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const nodeKey = gestaltsUtils.keyFromNode(nodeId); - if ( - (await this.db.get(this.graphNodesDbDomain, nodeKey)) == - null - ) { - return; - } - const perm = await this.acl.getNodePerm(nodeId); - if (perm == null) { - return; - } - return perm.gestalt; - }); - }); + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getGestaltActionsByNode(nodeId, tran), + ); + } + const nodeKey = gestaltsUtils.keyFromNode(nodeId); + const nodeKeyPath = [ + ...this.gestaltGraphNodesDbPath, + nodeKey, + ] as unknown as KeyPath; + if ((await tran.get(nodeKeyPath)) == null) { + return; + } + const perm = await this.acl.getNodePerm(nodeId, tran); + if (perm == null) { + return; + } + return perm.gestalt; } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) public async getGestaltActionsByIdentity( providerId: ProviderId, identityId: IdentityId, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const identityKey = gestaltsUtils.keyFromIdentity( - providerId, - identityId, - ); - if ( - (await this.db.get( - this.graphIdentitiesDbDomain, - identityKey, - )) == null - ) { - return; - } - const gestaltKeySet = (await this.db.get( - this.graphMatrixDbDomain, - identityKey, - )) as GestaltKeySet; - let nodeId: NodeId | undefined; - for (const nodeKey in gestaltKeySet) { - nodeId = gestaltsUtils.nodeFromKey(nodeKey as GestaltNodeKey); - break; - } - if (nodeId == null) { - return; - } - const perm = await this.acl.getNodePerm(nodeId); - if (perm == null) { - return; - } - return perm.gestalt; - }); - }); + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getGestaltActionsByIdentity(providerId, identityId, tran), + ); + } + const identityKey = gestaltsUtils.keyFromIdentity(providerId, identityId); + const identityKeyPath = [ + ...this.gestaltGraphIdentitiesDbPath, + identityKey, + ] as unknown as KeyPath; + if ((await tran.get(identityKeyPath)) == null) { + return; + } + const gestaltKeyPath = [ + ...this.gestaltGraphMatrixDbPath, + identityKey, + ] as unknown as KeyPath; + const gestaltKeySet = (await tran.get( + gestaltKeyPath, + )) as GestaltKeySet; + let nodeId: NodeId | undefined; + for (const nodeKey in gestaltKeySet) { + nodeId = gestaltsUtils.nodeFromKey(nodeKey as GestaltNodeKey); + break; + } + if (nodeId == null) { + return; + } + const perm = await this.acl.getNodePerm(nodeId, tran); + if (perm == null) { + return; + } + return perm.gestalt; } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) public async setGestaltActionByNode( nodeId: NodeId, action: GestaltAction, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const nodeKey = gestaltsUtils.keyFromNode(nodeId); - if ( - (await this.db.get(this.graphNodesDbDomain, nodeKey)) == - null - ) { - throw new gestaltsErrors.ErrorGestaltsGraphNodeIdMissing(); - } - await this.acl.setNodeAction(nodeId, action); - }); - }); + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setGestaltActionByNode(nodeId, action, tran), + ); + } + const nodeKey = gestaltsUtils.keyFromNode(nodeId); + const nodeKeyPath = [ + ...this.gestaltGraphNodesDbPath, + nodeKey, + ] as unknown as KeyPath; + if ((await tran.get(nodeKeyPath)) == null) { + throw new gestaltsErrors.ErrorGestaltsGraphNodeIdMissing(); + } + await this.acl.setNodeAction(nodeId, action, tran); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) @@ -953,56 +817,58 @@ class GestaltGraph { providerId: ProviderId, identityId: IdentityId, action: GestaltAction, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const identityKey = gestaltsUtils.keyFromIdentity( - providerId, - identityId, - ); - if ( - (await this.db.get( - this.graphIdentitiesDbDomain, - identityKey, - )) == null - ) { - throw new gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing(); - } - const gestaltKeySet = (await this.db.get( - this.graphMatrixDbDomain, - identityKey, - )) as GestaltKeySet; - let nodeId: NodeId | undefined; - for (const nodeKey in gestaltKeySet) { - nodeId = gestaltsUtils.nodeFromKey(nodeKey as GestaltNodeKey); - break; - } - // If there are no linked nodes, this cannot proceed - if (nodeId == null) { - throw new gestaltsErrors.ErrorGestaltsGraphNodeIdMissing(); - } - await this.acl.setNodeAction(nodeId, action); - }); - }); + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setGestaltActionByIdentity(providerId, identityId, action, tran), + ); + } + const identityKey = gestaltsUtils.keyFromIdentity(providerId, identityId); + const identityKeyPath = [ + ...this.gestaltGraphIdentitiesDbPath, + identityKey, + ] as unknown as KeyPath; + if ((await tran.get(identityKeyPath)) == null) { + throw new gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing(); + } + const gestaltKeyPath = [ + ...this.gestaltGraphMatrixDbPath, + identityKey, + ] as unknown as KeyPath; + const gestaltKeySet = (await tran.get(gestaltKeyPath)) as GestaltKeySet; + let nodeId: NodeId | undefined; + for (const nodeKey in gestaltKeySet) { + nodeId = gestaltsUtils.nodeFromKey(nodeKey as GestaltNodeKey); + break; + } + // If there are no linked nodes, this cannot proceed + if (nodeId == null) { + throw new gestaltsErrors.ErrorGestaltsGraphNodeIdMissing(); + } + await this.acl.setNodeAction(nodeId, action, tran); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) public async unsetGestaltActionByNode( nodeId: NodeId, action: GestaltAction, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const nodeKey = gestaltsUtils.keyFromNode(nodeId); - if ( - (await this.db.get(this.graphNodesDbDomain, nodeKey)) == - null - ) { - throw new gestaltsErrors.ErrorGestaltsGraphNodeIdMissing(); - } - await this.acl.unsetNodeAction(nodeId, action); - }); - }); + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetGestaltActionByNode(nodeId, action, tran), + ); + } + const nodeKey = gestaltsUtils.keyFromNode(nodeId); + const nodeKeyPath = [ + ...this.gestaltGraphNodesDbPath, + nodeKey, + ] as unknown as KeyPath; + if ((await tran.get(nodeKeyPath)) == null) { + throw new gestaltsErrors.ErrorGestaltsGraphNodeIdMissing(); + } + await this.acl.unsetNodeAction(nodeId, action, tran); } @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) @@ -1010,92 +876,94 @@ class GestaltGraph { providerId: ProviderId, identityId: IdentityId, action: GestaltAction, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - return await this.acl._transaction(async () => { - const identityKey = gestaltsUtils.keyFromIdentity( - providerId, - identityId, - ); - if ( - (await this.db.get( - this.graphIdentitiesDbDomain, - identityKey, - )) == null - ) { - throw new gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing(); - } - const gestaltKeySet = (await this.db.get( - this.graphMatrixDbDomain, - identityKey, - )) as GestaltKeySet; - let nodeId: NodeId | undefined; - for (const nodeKey in gestaltKeySet) { - nodeId = gestaltsUtils.nodeFromKey(nodeKey as GestaltNodeKey); - break; - } - // If there are no linked nodes, this cannot proceed - if (nodeId == null) { - throw new gestaltsErrors.ErrorGestaltsGraphNodeIdMissing(); - } - await this.acl.unsetNodeAction(nodeId, action); - }); - }); + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetGestaltActionByIdentity(providerId, identityId, action, tran), + ); + } + const identityKey = gestaltsUtils.keyFromIdentity(providerId, identityId); + const identityKeyPath = [ + ...this.gestaltGraphIdentitiesDbPath, + identityKey, + ] as unknown as KeyPath; + if ((await tran.get(identityKeyPath)) == null) { + throw new gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing(); + } + const gestaltKeyPath = [ + ...this.gestaltGraphMatrixDbPath, + identityKey, + ] as unknown as KeyPath; + const gestaltKeySet = (await tran.get(gestaltKeyPath)) as GestaltKeySet; + let nodeId: NodeId | undefined; + for (const nodeKey in gestaltKeySet) { + nodeId = gestaltsUtils.nodeFromKey(nodeKey as GestaltNodeKey); + break; + } + // If there are no linked nodes, this cannot proceed + if (nodeId == null) { + throw new gestaltsErrors.ErrorGestaltsGraphNodeIdMissing(); + } + await this.acl.unsetNodeAction(nodeId, action, tran); } protected async getGestaltByKey( gK: GestaltKey, + tran: DBTransaction, ): Promise { - return await this._transaction(async () => { - const gestalt: Gestalt = { - matrix: {}, - nodes: {}, - identities: {}, - }; - // We are not using traverseGestalt - // because this requires keeping track of the vertexKeys - const queue = [gK]; - const visited = new Set(); - while (true) { - const vertex = queue.shift(); - if (vertex == null) { - break; - } - const vertexKeys = await this.db.get( - this.graphMatrixDbDomain, - vertex, - ); - if (vertexKeys == null) { - return; - } - const gId = gestaltsUtils.ungestaltKey(vertex); - gestalt.matrix[vertex] = vertexKeys; - if (gId.type === 'node') { - const nodeInfo = await this.db.get( - this.graphNodesDbDomain, - vertex as GestaltNodeKey, - ); - gestalt.nodes[vertex] = nodeInfo!; - } else if (gId.type === 'identity') { - const identityInfo = await this.db.get( - this.graphIdentitiesDbDomain, - vertex as GestaltIdentityKey, - ); - gestalt.identities[vertex] = identityInfo!; - } - visited.add(vertex); - const neighbours: Array = Object.keys(vertexKeys).filter( - (k: GestaltKey) => !visited.has(k), - ) as Array; - queue.push(...neighbours); + const gestalt: Gestalt = { + matrix: {}, + nodes: {}, + identities: {}, + }; + // We are not using traverseGestalt + // because this requires keeping track of the vertexKeys + const queue = [gK]; + const visited = new Set(); + while (true) { + const vertex = queue.shift(); + if (vertex == null) { + break; } - return gestalt; - }); + const vertexPath = [ + ...this.gestaltGraphMatrixDbPath, + vertex, + ] as unknown as KeyPath; + const vertexKeys = await tran.get(vertexPath); + if (vertexKeys == null) { + return; + } + const gId = gestaltsUtils.ungestaltKey(vertex); + gestalt.matrix[vertex] = vertexKeys; + if (gId.type === 'node') { + const nodePath = [ + ...this.gestaltGraphNodesDbPath, + vertex as GestaltNodeKey, + ] as unknown as KeyPath; + const nodeInfo = await tran.get(nodePath); + gestalt.nodes[vertex] = nodeInfo!; + } else if (gId.type === 'identity') { + const identityPath = [ + ...this.gestaltGraphIdentitiesDbPath, + vertex as GestaltIdentityKey, + ] as unknown as KeyPath; + const identityInfo = await tran.get(identityPath); + gestalt.identities[vertex] = identityInfo!; + } + visited.add(vertex); + const neighbours: Array = Object.keys(vertexKeys).filter( + (k: GestaltKey) => !visited.has(k), + ) as Array; + queue.push(...neighbours); + } + return gestalt; } protected async traverseGestalt( queueStart: Array, visitedStart: Array = [], + tran: DBTransaction, ): Promise<[Set, Set, Set]> { const queue = [...queueStart]; const visited = new Set(visitedStart); @@ -1114,10 +982,11 @@ class GestaltGraph { if (vertex == null) { break; } - const vertexKeys = await this.db.get( - this.graphMatrixDbDomain, + const vertexPath = [ + ...this.gestaltGraphMatrixDbPath, vertex, - ); + ] as unknown as KeyPath; + const vertexKeys = await tran.get(vertexPath); if (vertexKeys == null) { break; } @@ -1135,11 +1004,6 @@ class GestaltGraph { } return [visited, visitedNodes, visitedIdentities]; } - - @ready(new gestaltsErrors.ErrorGestaltsGraphNotRunning()) - public async clearDB() { - await this.graphDb.clear(); - } } export default GestaltGraph; diff --git a/src/gestalts/errors.ts b/src/gestalts/errors.ts index b44eb0af6..ed11e46e1 100644 --- a/src/gestalts/errors.ts +++ b/src/gestalts/errors.ts @@ -1,16 +1,31 @@ -import { ErrorPolykey } from '../errors'; +import { ErrorPolykey, sysexits } from '../errors'; -class ErrorGestalts extends ErrorPolykey {} +class ErrorGestalts extends ErrorPolykey {} -class ErrorGestaltsGraphRunning extends ErrorGestalts {} +class ErrorGestaltsGraphRunning extends ErrorGestalts { + static description = 'GestaltGraph is running'; + exitCode = sysexits.USAGE; +} -class ErrorGestaltsGraphNotRunning extends ErrorGestalts {} +class ErrorGestaltsGraphNotRunning extends ErrorGestalts { + static description = 'GestaltGraph is not running'; + exitCode = sysexits.USAGE; +} -class ErrorGestaltsGraphDestroyed extends ErrorGestalts {} +class ErrorGestaltsGraphDestroyed extends ErrorGestalts { + static description = 'GestaltGraph is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorGestaltsGraphNodeIdMissing extends ErrorGestalts {} +class ErrorGestaltsGraphNodeIdMissing extends ErrorGestalts { + static description = 'Could not find NodeId'; + exitCode = sysexits.NOUSER; +} -class ErrorGestaltsGraphIdentityIdMissing extends ErrorGestalts {} +class ErrorGestaltsGraphIdentityIdMissing extends ErrorGestalts { + static description = 'Could not find IdentityId'; + exitCode = sysexits.NOUSER; +} export { ErrorGestalts, diff --git a/src/gestalts/utils.ts b/src/gestalts/utils.ts index 1f1df121f..2bba234e6 100644 --- a/src/gestalts/utils.ts +++ b/src/gestalts/utils.ts @@ -11,7 +11,7 @@ import type { NodeId } from '../nodes/types'; import type { IdentityId, ProviderId } from '../identities/types'; import canonicalize from 'canonicalize'; import { gestaltActions } from './types'; -import { utils as nodesUtils } from '../nodes'; +import * as nodesUtils from '../nodes/utils'; /** * Construct GestaltKey from GestaltId diff --git a/src/git/errors.ts b/src/git/errors.ts index 7995b7aeb..e2f265e32 100644 --- a/src/git/errors.ts +++ b/src/git/errors.ts @@ -1,18 +1,30 @@ -import { ErrorPolykey } from '../errors'; +import { ErrorPolykey, sysexits } from '../errors'; -class ErrorGit extends ErrorPolykey {} +class ErrorGit extends ErrorPolykey {} -class ErrorRepositoryUndefined extends ErrorGit {} +class ErrorRepositoryUndefined extends ErrorGit {} -class ErrorGitPermissionDenied extends ErrorGit {} +class ErrorGitPermissionDenied extends ErrorGit {} -class ErrorGitUndefinedRefs extends ErrorGit {} +class ErrorGitUndefinedRefs extends ErrorGit { + static description = 'Invalid ref'; + exitCode = sysexits.UNKNOWN; +} -class ErrorGitUndefinedType extends ErrorGit {} +class ErrorGitUndefinedType extends ErrorGit { + static description = 'Invalid data type'; + exitCode = sysexits.CONFIG; +} -class ErrorGitReadObject extends ErrorGit {} +class ErrorGitReadObject extends ErrorGit { + static description = 'Failed to read object'; + exitCode = sysexits.IOERR; +} -class ErrorGitUnimplementedMethod extends ErrorGit {} +class ErrorGitUnimplementedMethod extends ErrorGit { + static description = 'Invalid request'; + exitCode = sysexits.USAGE; +} export { ErrorGit, diff --git a/src/grpc/GRPCClient.ts b/src/grpc/GRPCClient.ts index b55d3a275..4e88291a1 100644 --- a/src/grpc/GRPCClient.ts +++ b/src/grpc/GRPCClient.ts @@ -129,7 +129,7 @@ abstract class GRPCClient { } catch (e) { // If we fail here then we leak the client object... client.close(); - throw new grpcErrors.ErrorGRPCClientTimeout(); + throw new grpcErrors.ErrorGRPCClientTimeout(e.message, { cause: e }); } let serverCertChain: Array | undefined; if (channelCredentials._isSecure()) { @@ -152,7 +152,10 @@ abstract class GRPCClient { ); const e_ = new grpcErrors.ErrorGRPCClientVerification( `${e.name}: ${e.message}`, - e.data, + { + data: e.data, + cause: e, + }, ); session.destroy(e_, http2.constants.NGHTTP2_PROTOCOL_ERROR); } @@ -264,6 +267,14 @@ abstract class GRPCClient { ); } + /** + * Gets information about the client + * Useful for error reporting + */ + public getClientInfo() { + return { nodeId: this.nodeId, host: this.host, port: this.port }; + } + /** * Gets the leaf server certificate if the connection is encrypted * Don't use this when using network proxies diff --git a/src/grpc/GRPCServer.ts b/src/grpc/GRPCServer.ts index 7d6ab3d35..fb9218e3a 100644 --- a/src/grpc/GRPCServer.ts +++ b/src/grpc/GRPCServer.ts @@ -70,12 +70,13 @@ class GRPCServer { try { this.port = await bindAsync(address, serverCredentials); } catch (e) { - throw new grpcErrors.ErrorGRPCServerBind(e.message); + throw new grpcErrors.ErrorGRPCServerBind(e.message, { cause: e }); } if (serverCredentials._isSecure()) { // @ts-ignore hack for private property - const http2Servers = server.http2ServerList as Array; - for (const http2Server of http2Servers) { + const http2Servers = server.http2ServerList; + for (const http2ServerObjects of http2Servers) { + const http2Server = http2ServerObjects.server as Http2SecureServer; http2Server.on('session', (session: Http2Session) => { const socket = session.socket as TLSSocket; const address = networkUtils.buildAddress( @@ -101,7 +102,10 @@ class GRPCServer { ); const e_ = new grpcErrors.ErrorGRPCServerVerification( `${e.name}: ${e.message}`, - e.data, + { + data: e.data, + cause: e, + }, ); session.destroy(e_, http2.constants.NGHTTP2_PROTOCOL_ERROR); } else { @@ -140,7 +144,7 @@ class GRPCServer { ...(timer != null ? [timer.timerP] : []), ]); } catch (e) { - throw new grpcErrors.ErrorGRPCServerShutdown(e.message); + throw new grpcErrors.ErrorGRPCServerShutdown(e.message, { cause: e }); } finally { if (timer != null) timerStop(timer); } @@ -196,7 +200,8 @@ class GRPCServer { this.logger.info(`Updating ${this.constructor.name} TLS Config`); // @ts-ignore hack for private property const http2Servers = this.server.http2ServerList; - for (const http2Server of http2Servers as Array) { + for (const http2ServerObjects of http2Servers) { + const http2Server = http2ServerObjects.server as Http2SecureServer; http2Server.setSecureContext({ key: Buffer.from(tlsConfig.keyPrivatePem, 'ascii'), cert: Buffer.from(tlsConfig.certChainPem, 'ascii'), diff --git a/src/grpc/errors.ts b/src/grpc/errors.ts index ccac769e3..023dffdc3 100644 --- a/src/grpc/errors.ts +++ b/src/grpc/errors.ts @@ -1,32 +1,51 @@ -import { ErrorPolykey } from '../errors'; +import { ErrorPolykey, sysexits } from '../errors'; -class ErrorGRPC extends ErrorPolykey {} +class ErrorGRPC extends ErrorPolykey {} -class ErrorGRPCClientTimeout extends ErrorGRPC { - description = 'Client connection timed out'; +class ErrorGRPCClientTimeout extends ErrorGRPC { + static description = 'Client connection timed out'; + exitCode = sysexits.UNAVAILABLE; } -class ErrorGRPCClientVerification extends ErrorGRPC { - description = 'Client could not verify server certificate'; +class ErrorGRPCClientVerification extends ErrorGRPC { + static description = 'Client could not verify server certificate'; + exitCode = sysexits.UNAVAILABLE; } -class ErrorGRPCClientChannelNotReady extends ErrorGRPC { - description = 'Client channel or subchannel is not ready'; +class ErrorGRPCClientChannelNotReady extends ErrorGRPC { + static description = 'Client channel or subchannel is not ready'; + exitCode = sysexits.UNAVAILABLE; } -class ErrorGRPCClientCall extends ErrorGRPC { - description = 'Generic call error'; +class ErrorGRPCClientCall extends ErrorGRPC { + static description = 'Generic call error'; + exitCode = sysexits.UNAVAILABLE; } -class ErrorGRPCServerNotRunning extends ErrorGRPC {} +class ErrorGRPCServerNotRunning extends ErrorGRPC { + static description = 'GRPC Server is not running'; + exitCode = sysexits.USAGE; +} -class ErrorGRPCServerBind extends ErrorGRPC {} +class ErrorGRPCServerBind extends ErrorGRPC { + static description = 'Could not bind to server'; + exitCode = sysexits.UNAVAILABLE; +} -class ErrorGRPCServerShutdown extends ErrorGRPC {} +class ErrorGRPCServerShutdown extends ErrorGRPC { + static description = 'Error during shutdown'; + exitCode = sysexits.UNAVAILABLE; +} -class ErrorGRPCServerNotSecured extends ErrorGRPC {} +class ErrorGRPCServerNotSecured extends ErrorGRPC { + static description = 'Server is not secured'; + exitCode = sysexits.NOPERM; +} -class ErrorGRPCServerVerification extends ErrorGRPC {} +class ErrorGRPCServerVerification extends ErrorGRPC { + static description = 'Failed to verify server certificate'; + exitCode = sysexits.UNAVAILABLE; +} export { ErrorGRPC, diff --git a/src/grpc/utils/utils.ts b/src/grpc/utils/utils.ts index 7b28d4c38..f99331585 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -28,10 +28,14 @@ import type { AsyncGeneratorDuplexStreamClient, } from '../types'; import type { CertificatePemChain, PrivateKeyPem } from '../../keys/types'; +import type { POJO } from '../../types'; import { Buffer } from 'buffer'; +import { AbstractError } from '@matrixai/errors'; import * as grpc from '@grpc/grpc-js'; import * as grpcErrors from '../errors'; import * as errors from '../../errors'; +import * as networkUtils from '../../network/utils'; +import * as nodesUtils from '../../nodes/utils'; import { promisify, promise, never } from '../../utils/utils'; /** @@ -158,17 +162,19 @@ function getServerSession(call: ServerSurfaceCall): Http2Session { * Serializes Error instances into GRPC errors * Use this on the sending side to send exceptions * Do not send exceptions to clients you do not trust + * If sending to an agent (rather than a client), set sensitive to true to + * prevent sensitive information from being sent over the network */ -function fromError(error: Error): ServerStatusResponse { +function fromError( + error: Error, + sensitive: boolean = false, +): ServerStatusResponse { const metadata = new grpc.Metadata(); - // If the error is not ErrorPolykey, wrap it up so it can be serialised - // TODO: add additional metadata regarding the network location of the error - if (!(error instanceof errors.ErrorPolykey)) { - error = new errors.ErrorPolykey(error.message); + if (sensitive) { + metadata.set('error', JSON.stringify(error, sensitiveReplacer)); + } else { + metadata.set('error', JSON.stringify(error, replacer)); } - metadata.set('name', error.name); - metadata.set('message', error.message); - metadata.set('data', JSON.stringify((error as errors.ErrorPolykey).data)); return { metadata, }; @@ -178,10 +184,9 @@ function fromError(error: Error): ServerStatusResponse { * Deserialized GRPC errors into ErrorPolykey * Use this on the receiving side to receive exceptions */ -function toError(e: ServiceError): errors.ErrorPolykey { - const errorName = e.metadata.get('name')[0] as string; - const errorMessage = e.metadata.get('message')[0] as string; - const errorData = e.metadata.get('data')[0] as string; +function toError(e: ServiceError): errors.ErrorPolykey { + const errorData = e.metadata.get('error')[0].toString(); + const connInfo = e.metadata.get('metadata')[0].toString(); // Grpc.status is an enum // this will iterate the enum values then enum keys // they will all be of string type @@ -190,19 +195,19 @@ function toError(e: ServiceError): errors.ErrorPolykey { // check if the error code matches a known grpc status // @ts-ignore grpc.status[key] is in fact a string if (isNaN(parseInt(key)) && e.code === grpc.status[key]) { - if ( - key === 'UNKNOWN' && - errorName != null && - errorMessage != null && - errorData != null && - errorName in errors - ) { - return new errors[errorName](errorMessage, JSON.parse(errorData)); + if (key === 'UNKNOWN' && errorData != null) { + const error: Error = JSON.parse(errorData, reviver); + return new errors.ErrorPolykeyRemote(error.message, { + data: JSON.parse(connInfo), + cause: error, + }); } else { return new grpcErrors.ErrorGRPCClientCall(e.message, { - code: e.code, - details: e.details, - metadata: e.metadata.getMap(), + data: { + code: e.code, + details: e.details, + metadata: e.metadata.getMap(), + }, }); } } @@ -210,6 +215,148 @@ function toError(e: ServiceError): errors.ErrorPolykey { never(); } +/** + * Replacer function for serialising errors over GRPC (used by `JSON.stringify` + * in `fromError`) + * Polykey errors are handled by their inbuilt `toJSON` method , so this only + * serialises other errors + */ +function replacer(key: string, value: any): any { + if (value instanceof AggregateError) { + // AggregateError has an `errors` property + return { + type: value.constructor.name, + data: { + errors: value.errors, + message: value.message, + stack: value.stack, + }, + }; + } else if (value instanceof Error) { + // If it's some other type of error then only serialise the message and + // stack (and the type of the error) + return { + type: value.name, + data: { + message: value.message, + stack: value.stack, + }, + }; + } else { + // If it's not an error then just leave as is + return value; + } +} + +/** + * The same as `replacer`, however this will additionally filter out any + * sensitive data that should not be sent over the network when sending to an + * agent (as opposed to a client) + */ +function sensitiveReplacer(key: string, value: any) { + if (key === 'stack') { + return; + } else { + return replacer(key, value); + } +} + +/** + * Error constructors for non-Polykey errors + * Allows these errors to be reconstructed from GRPC metadata + */ +const standardErrors = { + Error, + TypeError, + SyntaxError, + ReferenceError, + EvalError, + RangeError, + URIError, + AggregateError, + AbstractError, +}; + +/** + * Reviver function for deserialising errors sent over GRPC (used by + * `JSON.parse` in `toError`) + * The final result returned will always be an error - if the deserialised + * data is of an unknown type then this will be wrapped as an + * `ErrorPolykeyUnknown` + */ +function reviver(key: string, value: any): any { + // If the value is an error then reconstruct it + if ( + typeof value === 'object' && + typeof value.type === 'string' && + typeof value.data === 'object' + ) { + try { + let eClass = errors[value.type]; + if (eClass != null) return eClass.fromJSON(value); + eClass = standardErrors[value.type]; + if (eClass != null) { + let e; + switch (eClass) { + case AbstractError: + return eClass.fromJSON(); + case AggregateError: + if ( + !Array.isArray(value.data.errors) || + typeof value.data.message !== 'string' || + ('stack' in value.data && typeof value.data.stack !== 'string') + ) { + throw new TypeError(`cannot decode JSON to ${value.type}`); + } + e = new eClass(value.data.errors, value.data.message); + e.stack = value.data.stack; + break; + default: + if ( + typeof value.data.message !== 'string' || + ('stack' in value.data && typeof value.data.stack !== 'string') + ) { + throw new TypeError(`Cannot decode JSON to ${value.type}`); + } + e = new eClass(value.data.message); + e.stack = value.data.stack; + break; + } + return e; + } + } catch (e) { + // If `TypeError` which represents decoding failure + // then return value as-is + // Any other exception is a bug + if (!(e instanceof TypeError)) { + throw e; + } + } + // Other values are returned as-is + return value; + } else if (key === '') { + // Root key will be '' + // Reaching here means the root JSON value is not a valid exception + // Therefore ErrorPolykeyUnknown is only ever returned at the top-level + const error = new errors.ErrorPolykeyUnknown('Unknown error JSON', { + data: { + json: value, + }, + }); + return error; + } else if (key === 'timestamp') { + // Encode timestamps + const timestampParsed = Date.parse(value); + if (!isNaN(timestampParsed)) { + return new Date(timestampParsed); + } else { + return undefined; + } + } else { + return value; + } +} + /** * Converts GRPC unary call to promisified unary call * Used on the client side @@ -217,6 +364,7 @@ function toError(e: ServiceError): errors.ErrorPolykey { */ function promisifyUnaryCall( client: Client, + metadata: POJO, f: (...args: any[]) => ClientUnaryCall, ): (...args: any[]) => PromiseUnaryCall { return (...args) => { @@ -228,6 +376,10 @@ function promisifyUnaryCall( const { p: pMeta, resolveP: resolveMetaP } = promise(); const callback = (error: ServiceError, ...values) => { if (error != null) { + if ('nodeId' in metadata) { + metadata.nodeId = nodesUtils.encodeNodeId(metadata.nodeId); + } + error.metadata.set('metadata', JSON.stringify(metadata)); rejectP(toError(error)); return; } @@ -253,13 +405,30 @@ function promisifyUnaryCall( */ function generatorReadable( stream: ClientReadableStream, + metadata: POJO, ): AsyncGeneratorReadableStream>; function generatorReadable( stream: ServerReadableStream, + metadata: POJO, ): AsyncGeneratorReadableStream>; function generatorReadable( stream: ClientReadableStream | ServerReadableStream, + metadata: POJO, ) { + const peerAddress = stream + .getPeer() + .match( + /([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}:\d{1,5}|(\d{1,3}\.){3}\d{1,3}:\d{1,5}/, + ); + if (!('host' in metadata) && peerAddress != null) { + metadata.host = networkUtils.parseAddress(peerAddress[0])[0]; + } + if (!('port' in metadata) && peerAddress != null) { + metadata.port = networkUtils.parseAddress(peerAddress[0])[1]; + } + if ('nodeId' in metadata) { + metadata.nodeId = nodesUtils.encodeNodeId(metadata.nodeId); + } const gf = async function* () { try { let vR = yield; @@ -280,6 +449,7 @@ function generatorReadable( } } catch (e) { stream.destroy(); + e.metadata.set('metadata', JSON.stringify(metadata)); throw toError(e); } }; @@ -297,6 +467,7 @@ function generatorReadable( */ function promisifyReadableStreamCall( client: grpc.Client, + metadata: POJO, f: (...args: any[]) => ClientReadableStream, ): ( ...args: any[] @@ -309,6 +480,7 @@ function promisifyReadableStreamCall( }); const g = generatorReadable( stream, + metadata, ) as AsyncGeneratorReadableStreamClient>; g.meta = pMeta; return g; @@ -324,12 +496,15 @@ function promisifyReadableStreamCall( */ function generatorWritable( stream: ClientWritableStream, + sensitive: boolean, ): AsyncGeneratorWritableStream>; function generatorWritable( stream: ServerWritableStream, + sensitive: boolean, ): AsyncGeneratorWritableStream>; function generatorWritable( stream: ClientWritableStream | ServerWritableStream, + sensitive: boolean = false, ) { const streamWrite = promisify(stream.write).bind(stream); const gf = async function* () { @@ -338,7 +513,7 @@ function generatorWritable( try { vW = yield; } catch (e) { - stream.emit('error', fromError(e)); + stream.emit('error', fromError(e, sensitive)); stream.end(); return; } @@ -364,6 +539,7 @@ function generatorWritable( */ function promisifyWritableStreamCall( client: grpc.Client, + metadata: POJO, f: (...args: any[]) => ClientWritableStream, ): ( ...args: any[] @@ -379,6 +555,10 @@ function promisifyWritableStreamCall( }; const callback = (error, ...values) => { if (error != null) { + if ('nodeId' in metadata) { + metadata.nodeId = nodesUtils.encodeNodeId(metadata.nodeId); + } + error.metadata.set('metadata', JSON.stringify(metadata)); return rejectP(toError(error)); } return resolveP(values.length === 1 ? values[0] : values); @@ -391,6 +571,7 @@ function promisifyWritableStreamCall( }); const g = generatorWritable( stream, + false, ) as AsyncGeneratorWritableStreamClient< TWrite, ClientWritableStream @@ -410,15 +591,21 @@ function promisifyWritableStreamCall( */ function generatorDuplex( stream: ClientDuplexStream, + metadata: POJO, + sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ServerDuplexStream, + metadata: POJO, + sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ClientDuplexStream | ServerDuplexStream, + metadata: POJO, + sensitive: boolean = false, ) { - const gR = generatorReadable(stream as any); - const gW = generatorWritable(stream as any); + const gR = generatorReadable(stream as any, metadata); + const gW = generatorWritable(stream as any, sensitive); const gf = async function* () { let vR: any, vW: any; while (true) { @@ -467,6 +654,7 @@ function generatorDuplex( */ function promisifyDuplexStreamCall( client: grpc.Client, + metadata: POJO, f: (...args: any[]) => ClientDuplexStream, ): ( ...args: any[] @@ -483,6 +671,8 @@ function promisifyDuplexStreamCall( }); const g = generatorDuplex( stream, + metadata, + false, ) as AsyncGeneratorDuplexStreamClient< TRead, TWrite, diff --git a/src/identities/IdentitiesManager.ts b/src/identities/IdentitiesManager.ts index c007c8883..83c92334e 100644 --- a/src/identities/IdentitiesManager.ts +++ b/src/identities/IdentitiesManager.ts @@ -4,15 +4,14 @@ import type { ProviderTokens, TokenData, } from './types'; -import type { DB, DBLevel } from '@matrixai/db'; +import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type Provider from './Provider'; - -import { Mutex } from 'async-mutex'; import Logger from '@matrixai/logger'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; +import { withF } from '@matrixai/resources'; import * as identitiesErrors from './errors'; interface IdentitiesManager extends CreateDestroyStartStop {} @@ -21,18 +20,6 @@ interface IdentitiesManager extends CreateDestroyStartStop {} new identitiesErrors.ErrorIdentitiesManagerDestroyed(), ) class IdentitiesManager { - protected logger: Logger; - protected db: DB; - protected identitiesDbDomain: string = this.constructor.name; - protected identitiesTokensDbDomain: Array = [ - this.identitiesDbDomain, - 'tokens', - ]; - protected identitiesDb: DBLevel; - protected identitiesTokensDb: DBLevel; - protected lock: Mutex = new Mutex(); - protected providers: Map = new Map(); - static async createIdentitiesManager({ db, logger = new Logger(this.name), @@ -49,29 +36,29 @@ class IdentitiesManager { return identitiesManager; } + protected logger: Logger; + protected db: DB; + protected identitiesDbPath: LevelPath = [this.constructor.name]; + /** + * Tokens stores ProviderId -> ProviderTokens + */ + protected identitiesTokensDbPath: LevelPath = [ + this.constructor.name, + 'tokens', + ]; + protected providers: Map = new Map(); + constructor({ db, logger }: { db: DB; logger: Logger }) { this.logger = logger; this.db = db; } - get locked(): boolean { - return this.lock.isLocked(); - } - public async start({ fresh = false }: { fresh?: boolean } = {}) { this.logger.info(`Starting ${this.constructor.name}`); - const identitiesDb = await this.db.level(this.identitiesDbDomain); - // Tokens stores ProviderId -> ProviderTokens - const identitiesTokensDb = await this.db.level( - this.identitiesTokensDbDomain[1], - identitiesDb, - ); if (fresh) { - await identitiesDb.clear(); + await this.db.clear(this.identitiesDbPath); this.providers = new Map(); } - this.identitiesDb = identitiesDb; - this.identitiesTokensDb = identitiesTokensDb; this.logger.info(`Started ${this.constructor.name}`); } @@ -82,38 +69,16 @@ class IdentitiesManager { async destroy() { this.logger.info(`Destroying ${this.constructor.name}`); - const identitiesDb = await this.db.level(this.identitiesDbDomain); - await identitiesDb.clear(); + await this.db.clear(this.identitiesDbPath); this.providers = new Map(); this.logger.info(`Destroyed ${this.constructor.name}`); } - /** - * Run several operations within the same lock - * This does not ensure atomicity of the underlying database - * Database atomicity still depends on the underlying operation - */ - public async transaction( - f: (identitiesManager: IdentitiesManager) => Promise, + @ready(new identitiesErrors.ErrorIdentitiesManagerNotRunning()) + public async withTransactionF( + f: (tran: DBTransaction) => Promise, ): Promise { - const release = await this.lock.acquire(); - try { - return await f(this); - } finally { - release(); - } - } - - /** - * Transaction wrapper that will not lock if the operation was executed - * within a transaction context - */ - public async _transaction(f: () => Promise): Promise { - if (this.lock.isLocked()) { - return await f(); - } else { - return await this.transaction(f); - } + return withF([this.db.transaction()], ([tran]) => f(tran)); } @ready(new identitiesErrors.ErrorIdentitiesManagerNotRunning()) @@ -146,34 +111,46 @@ class IdentitiesManager { } @ready(new identitiesErrors.ErrorIdentitiesManagerNotRunning()) - public async getTokens(providerId: ProviderId): Promise { - return await this._transaction(async () => { - const providerTokens = await this.db.get( - this.identitiesTokensDbDomain, - providerId, + public async getTokens( + providerId: ProviderId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getTokens(providerId, tran), ); - if (providerTokens == null) { - return {}; - } - return providerTokens; - }); + } + const providerIdPath = [ + ...this.identitiesTokensDbPath, + providerId, + ] as unknown as KeyPath; + const providerTokens = await tran.get(providerIdPath); + if (providerTokens == null) { + return {}; + } + return providerTokens; } @ready(new identitiesErrors.ErrorIdentitiesManagerNotRunning()) public async getToken( providerId: ProviderId, identityId: IdentityId, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const providerTokens = await this.db.get( - this.identitiesTokensDbDomain, - providerId, + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getToken(providerId, identityId, tran), ); - if (providerTokens == null) { - return undefined; - } - return providerTokens[identityId]; - }); + } + const providerIdPath = [ + ...this.identitiesTokensDbPath, + providerId, + ] as unknown as KeyPath; + const providerTokens = await tran.get(providerIdPath); + if (providerTokens == null) { + return undefined; + } + return providerTokens[identityId]; } @ready(new identitiesErrors.ErrorIdentitiesManagerNotRunning()) @@ -181,39 +158,47 @@ class IdentitiesManager { providerId: ProviderId, identityId: IdentityId, tokenData: TokenData, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const providerTokens = await this.getTokens(providerId); - providerTokens[identityId] = tokenData; - await this.db.put( - this.identitiesTokensDbDomain, - providerId, - providerTokens, + if (tran == null) { + return this.withTransactionF(async (tran) => + this.putToken(providerId, identityId, tokenData, tran), ); - }); + } + const providerTokens = await this.getTokens(providerId); + providerTokens[identityId] = tokenData; + const providerIdPath = [ + ...this.identitiesTokensDbPath, + providerId, + ] as unknown as KeyPath; + await tran.put(providerIdPath, providerTokens); } @ready(new identitiesErrors.ErrorIdentitiesManagerNotRunning()) public async delToken( providerId: ProviderId, identityId: IdentityId, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const providerTokens = await this.getTokens(providerId); - if (!(identityId in providerTokens)) { - return; - } - delete providerTokens[identityId]; - if (!Object.keys(providerTokens).length) { - await this.db.del(this.identitiesTokensDbDomain, providerId); - return; - } - await this.db.put( - this.identitiesTokensDbDomain, - providerId, - providerTokens, + if (tran == null) { + return this.withTransactionF(async (tran) => + this.delToken(providerId, identityId, tran), ); - }); + } + const providerTokens = await this.getTokens(providerId, tran); + if (!(identityId in providerTokens)) { + return; + } + delete providerTokens[identityId]; + const providerIdPath = [ + ...this.identitiesTokensDbPath, + providerId, + ] as unknown as KeyPath; + if (!Object.keys(providerTokens).length) { + await tran.del(providerIdPath); + return; + } + await tran.put(providerIdPath, providerTokens); } } diff --git a/src/identities/errors.ts b/src/identities/errors.ts index 0effd2306..40ade2ceb 100644 --- a/src/identities/errors.ts +++ b/src/identities/errors.ts @@ -1,24 +1,52 @@ -import { ErrorPolykey } from '../errors'; - -class ErrorIdentities extends ErrorPolykey {} - -class ErrorIdentitiesManagerRunning extends ErrorIdentities {} - -class ErrorIdentitiesManagerNotRunning extends ErrorIdentities {} - -class ErrorIdentitiesManagerDestroyed extends ErrorIdentities {} - -class ErrorProviderDuplicate extends ErrorIdentities {} - -class ErrorProviderCall extends ErrorIdentities {} - -class ErrorProviderAuthentication extends ErrorIdentities {} - -class ErrorProviderUnauthenticated extends ErrorIdentities {} - -class ErrorProviderUnimplemented extends ErrorIdentities {} - -class ErrorProviderMissing extends ErrorIdentities {} +import { ErrorPolykey, sysexits } from '../errors'; + +class ErrorIdentities extends ErrorPolykey {} + +class ErrorIdentitiesManagerRunning extends ErrorIdentities { + static description = 'IdentitiesManager is running'; + exitCode = sysexits.USAGE; +} + +class ErrorIdentitiesManagerNotRunning extends ErrorIdentities { + static description = 'IdentitiesManager is not running'; + exitCode = sysexits.USAGE; +} + +class ErrorIdentitiesManagerDestroyed extends ErrorIdentities { + static description = 'IdentitiesManager is destroyed'; + exitCode = sysexits.USAGE; +} + +class ErrorProviderDuplicate extends ErrorIdentities { + static description = 'Provider has already been registered'; + exitCode = sysexits.USAGE; +} + +class ErrorProviderCall extends ErrorIdentities { + static description = 'Invalid response received from provider'; + exitCode = sysexits.UNAVAILABLE; +} + +class ErrorProviderAuthentication extends ErrorIdentities { + static description = 'Could not authenticate provider'; + exitCode = sysexits.UNKNOWN; +} + +class ErrorProviderUnauthenticated extends ErrorIdentities { + static description = + 'Provider has not been authenticated or access token is expired or invalid'; + exitCode = sysexits.NOPERM; +} + +class ErrorProviderUnimplemented extends ErrorIdentities { + static description = 'Functionality is unavailable'; + exitCode = sysexits.USAGE; +} + +class ErrorProviderMissing extends ErrorIdentities { + static description = 'Provider has not been registered'; + exitCode = sysexits.USAGE; +} export { ErrorIdentities, diff --git a/src/identities/providers/github/GitHubProvider.ts b/src/identities/providers/github/GitHubProvider.ts index 4dc939999..8fd0a79fe 100644 --- a/src/identities/providers/github/GitHubProvider.ts +++ b/src/identities/providers/github/GitHubProvider.ts @@ -121,6 +121,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderAuthentication( 'Provider access token response is not valid JSON', + { cause: e }, ); } if (data.error) { @@ -200,6 +201,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderCall( `Provider response body is not valid JSON`, + { cause: e }, ); } return data.login; @@ -246,6 +248,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderCall( `Provider response body is not valid JSON`, + { cause: e }, ); } return { @@ -297,6 +300,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderCall( `Provider response body is not valid JSON`, + { cause: e }, ); } for (const item of data) { @@ -343,6 +347,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderCall( `Provider response body is not valid JSON`, + { cause: e }, ); } for (const item of data) { @@ -414,6 +419,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderCall( `Provider response body is not valid JSON`, + { cause: e }, ); } return { @@ -466,6 +472,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderCall( `Provider response body is not valid JSON`, + { cause: e }, ); } const linkClaimData = data.files[this.gistFilename]?.content; diff --git a/src/keys/KeyManager.ts b/src/keys/KeyManager.ts index 8addec87c..937c80d98 100644 --- a/src/keys/KeyManager.ts +++ b/src/keys/KeyManager.ts @@ -269,10 +269,13 @@ class KeyManager { }); } catch (e) { throw new keysErrors.ErrorRootKeysRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } try { @@ -414,10 +417,13 @@ class KeyManager { ); } catch (e) { throw new keysErrors.ErrorRootCertRenew(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } await this.garbageCollectRootCerts(); @@ -535,10 +541,13 @@ class KeyManager { } } catch (e) { throw new keysErrors.ErrorRootCertsGC(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } @@ -630,10 +639,13 @@ class KeyManager { return false; } throw new keysErrors.ErrorRootKeysRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } return true; @@ -649,10 +661,13 @@ class KeyManager { ]); } catch (e) { throw new keysErrors.ErrorRootKeysRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } let keyPair; @@ -665,7 +680,7 @@ class KeyManager { password, ); } catch (e) { - throw new keysErrors.ErrorRootKeysParse(e.message); + throw new keysErrors.ErrorRootKeysParse(e.message, { cause: e }); } return keyPair; } @@ -693,10 +708,13 @@ class KeyManager { ]); } catch (e) { throw new keysErrors.ErrorRootKeysWrite(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } @@ -717,10 +735,13 @@ class KeyManager { }); } catch (e) { throw new keysErrors.ErrorRootKeysRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } const rootKeyPairBits = keysUtils.publicKeyBitSize( @@ -764,10 +785,13 @@ class KeyManager { return false; } throw new keysErrors.ErrorDBKeyRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } return true; @@ -780,10 +804,13 @@ class KeyManager { keysDbKeyCipher = await this.fs.promises.readFile(keyPath); } catch (e) { throw new keysErrors.ErrorDBKeyRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } let keysDbKeyPlain; @@ -793,7 +820,7 @@ class KeyManager { keysDbKeyCipher, ); } catch (e) { - throw new keysErrors.ErrorDBKeyParse(e.message); + throw new keysErrors.ErrorDBKeyParse(e.message, { cause: e }); } return keysDbKeyPlain; } @@ -814,10 +841,13 @@ class KeyManager { await this.fs.promises.rename(`${keyPath}.tmp`, keyPath); } catch (e) { throw new keysErrors.ErrorDBKeyWrite(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } @@ -855,10 +885,13 @@ class KeyManager { return false; } throw new keysErrors.ErrorRootCertRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } return true; @@ -873,10 +906,13 @@ class KeyManager { }); } catch (e) { throw new keysErrors.ErrorRootCertRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } const rootCert = keysUtils.certFromPem(rootCertPem); @@ -894,10 +930,13 @@ class KeyManager { ); } catch (e) { throw new keysErrors.ErrorRootCertWrite(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } @@ -913,10 +952,13 @@ class KeyManager { rootCertsNames = await this.fs.promises.readdir(this.rootCertsPath); } catch (e) { throw new keysErrors.ErrorRootCertRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } rootCertsNames.sort((a, b) => { @@ -950,10 +992,13 @@ class KeyManager { ); } catch (e) { throw new keysErrors.ErrorRootCertRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } return rootCertsPems; diff --git a/src/keys/errors.ts b/src/keys/errors.ts index e239f3a4b..59863b617 100644 --- a/src/keys/errors.ts +++ b/src/keys/errors.ts @@ -1,50 +1,92 @@ import { ErrorPolykey, sysexits } from '../errors'; -class ErrorKeys extends ErrorPolykey {} +class ErrorKeys extends ErrorPolykey {} -class ErrorKeyManagerRunning extends ErrorKeys {} +class ErrorKeyManagerRunning extends ErrorKeys { + static description = 'KeyManager is running'; + exitCode = sysexits.USAGE; +} -class ErrorKeyManagerNotRunning extends ErrorKeys {} +class ErrorKeyManagerNotRunning extends ErrorKeys { + static description = 'KeyManager is not running'; + exitCode = sysexits.USAGE; +} -class ErrorKeyManagerDestroyed extends ErrorKeys {} +class ErrorKeyManagerDestroyed extends ErrorKeys { + static description = 'KeyManager is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorKeysPasswordInvalid extends ErrorKeys { - description = 'Password has invalid format'; +class ErrorKeysPasswordInvalid extends ErrorKeys { + static description = 'Password has invalid format'; exitCode = sysexits.USAGE; } -class ErrorKeysRecoveryCodeInvalid extends ErrorKeys { - description = 'Recovery code has invalid format'; +class ErrorKeysRecoveryCodeInvalid extends ErrorKeys { + static description = 'Recovery code has invalid format'; exitCode = sysexits.USAGE; } -class ErrorKeysRecoveryCodeIncorrect extends ErrorKeys { - description = +class ErrorKeysRecoveryCodeIncorrect extends ErrorKeys { + static description = "Recovered key pair's public key does not match the root public key"; exitCode = sysexits.USAGE; } -class ErrorRootKeysRead extends ErrorKeys {} +class ErrorRootKeysRead extends ErrorKeys { + static description = 'Unable to read root keypair'; + exitCode = sysexits.IOERR; +} -class ErrorRootKeysParse extends ErrorKeys {} +class ErrorRootKeysParse extends ErrorKeys { + static description = 'Unable to parse root keypair'; + exitCode = sysexits.IOERR; +} -class ErrorRootKeysWrite extends ErrorKeys {} +class ErrorRootKeysWrite extends ErrorKeys { + static description = 'Unable to write root keypair'; + exitCode = sysexits.IOERR; +} -class ErrorRootCertRead extends ErrorKeys {} +class ErrorRootCertRead extends ErrorKeys { + static description = 'Unable to read root certificate'; + exitCode = sysexits.IOERR; +} -class ErrorRootCertWrite extends ErrorKeys {} +class ErrorRootCertWrite extends ErrorKeys { + static description = 'Unable to write root certificate'; + exitCode = sysexits.IOERR; +} -class ErrorRootCertRenew extends ErrorKeys {} +class ErrorRootCertRenew extends ErrorKeys { + static description = 'Unable to renew root certificate'; + exitCode = sysexits.IOERR; +} -class ErrorRootCertsGC extends ErrorKeys {} +class ErrorRootCertsGC extends ErrorKeys { + static description = 'Unexpected error during garbage collection'; + exitCode = sysexits.IOERR; +} -class ErrorEncryptSize extends ErrorKeys {} +class ErrorEncryptSize extends ErrorKeys { + static description = 'Cannot encrypt data with key bit size'; + exitCode = sysexits.USAGE; +} -class ErrorDBKeyRead extends ErrorKeys {} +class ErrorDBKeyRead extends ErrorKeys { + static description = 'Unable to read key'; + exitCode = sysexits.IOERR; +} -class ErrorDBKeyWrite extends ErrorKeys {} +class ErrorDBKeyWrite extends ErrorKeys { + static description = 'Unable to write key'; + exitCode = sysexits.IOERR; +} -class ErrorDBKeyParse extends ErrorKeys {} +class ErrorDBKeyParse extends ErrorKeys { + static description = 'Unable to decrypt key'; + exitCode = sysexits.IOERR; +} export { ErrorKeys, diff --git a/src/network/ConnectionForward.ts b/src/network/ConnectionForward.ts index c41238a92..5e8a829d4 100644 --- a/src/network/ConnectionForward.ts +++ b/src/network/ConnectionForward.ts @@ -165,9 +165,12 @@ class ConnectionForward extends Connection { } this.utpSocket.off('message', this.handleMessage); throw new networkErrors.ErrorConnectionStart(e.message, { - code: e.code, - errno: e.errno, - syscall: e.syscall, + data: { + code: e.code, + errno: e.errno, + syscall: e.syscall, + }, + cause: e, }); } finally { clearInterval(punchInterval); diff --git a/src/network/ConnectionReverse.ts b/src/network/ConnectionReverse.ts index a746454bf..ada434649 100644 --- a/src/network/ConnectionReverse.ts +++ b/src/network/ConnectionReverse.ts @@ -157,9 +157,12 @@ class ConnectionReverse extends Connection { this.serverSocket.destroy(); this.utpSocket.off('message', this.handleMessage); throw new networkErrors.ErrorConnectionStart(e.message, { - code: e.code, - errno: e.errno, - syscall: e.syscall, + data: { + code: e.code, + errno: e.errno, + syscall: e.syscall, + }, + cause: e, }); } finally { clearInterval(punchInterval); @@ -247,9 +250,12 @@ class ConnectionReverse extends Connection { tlsSocket.destroy(); } throw new networkErrors.ErrorConnectionCompose(e.message, { - code: e.code, - errno: e.errno, - syscall: e.syscall, + data: { + code: e.code, + errno: e.errno, + syscall: e.syscall, + }, + cause: e, }); } tlsSocket.on('error', async (e) => { diff --git a/src/network/Proxy.ts b/src/network/Proxy.ts index 15bbf4d05..1a6ff46f1 100644 --- a/src/network/Proxy.ts +++ b/src/network/Proxy.ts @@ -7,8 +7,9 @@ import type UTPConnection from 'utp-native/lib/connection'; import type { ConnectionsReverse } from './ConnectionReverse'; import http from 'http'; import UTP from 'utp-native'; -import { Mutex } from 'async-mutex'; import Logger from '@matrixai/logger'; +import { Lock } from '@matrixai/async-locks'; +import { withF } from '@matrixai/resources'; import { StartStop, ready } from '@matrixai/async-init/dist/StartStop'; import ConnectionReverse from './ConnectionReverse'; import ConnectionForward from './ConnectionForward'; @@ -37,12 +38,12 @@ class Proxy { protected server: http.Server; protected utpSocket: UTP; protected tlsConfig: TLSConfig; - protected connectionLocksForward: Map = new Map(); + protected connectionLocksForward: Map = new Map(); protected connectionsForward: ConnectionsForward = { proxy: new Map(), client: new Map(), }; - protected connectionLocksReverse: Map = new Map(); + protected connectionLocksReverse: Map = new Map(); protected connectionsReverse: ConnectionsReverse = { proxy: new Map(), reverse: new Map(), @@ -316,24 +317,24 @@ class Proxy { const proxyAddress = networkUtils.buildAddress(proxyHost, proxyPort); let lock = this.connectionLocksForward.get(proxyAddress); if (lock == null) { - lock = new Mutex(); + lock = new Lock(); this.connectionLocksForward.set(proxyAddress, lock); } - const release = await lock.acquire(); - try { - await this.establishConnectionForward( - nodeId, - proxyHost, - proxyPort, - timer_, - ); - } finally { - if (timer === undefined) { - timerStop(timer_!); + await withF([lock.lock()], async () => { + try { + await this.establishConnectionForward( + nodeId, + proxyHost, + proxyPort, + timer_, + ); + } finally { + if (timer === undefined) { + timerStop(timer_!); + } + this.connectionLocksForward.delete(proxyAddress); } - release(); - this.connectionLocksForward.delete(proxyAddress); - } + }); } @ready(new networkErrors.ErrorProxyNotRunning(), true) @@ -344,20 +345,20 @@ class Proxy { const proxyAddress = networkUtils.buildAddress(proxyHost, proxyPort); let lock = this.connectionLocksForward.get(proxyAddress); if (lock == null) { - lock = new Mutex(); + lock = new Lock(); this.connectionLocksForward.set(proxyAddress, lock); } - const release = await lock.acquire(); - try { - const conn = this.connectionsForward.proxy.get(proxyAddress); - if (conn == null) { - return; + await withF([lock.lock()], async () => { + try { + const conn = this.connectionsForward.proxy.get(proxyAddress); + if (conn == null) { + return; + } + await conn.stop(); + } finally { + this.connectionLocksForward.delete(proxyAddress); } - await conn.stop(); - } finally { - release(); - this.connectionLocksForward.delete(proxyAddress); - } + }); } /** @@ -419,61 +420,71 @@ class Proxy { } let lock = this.connectionLocksForward.get(proxyAddress as Address); if (lock == null) { - lock = new Mutex(); + lock = new Lock(); this.connectionLocksForward.set(proxyAddress as Address, lock); } - const release = await lock.acquire(); - try { - const timer = timerStart(this.connConnectTime); + await withF([lock.lock()], async () => { try { - await this.connectForward( - nodeId, - proxyHost, - proxyPort, - clientSocket, - timer, - ); - } catch (e) { - if (e instanceof networkErrors.ErrorProxyConnectInvalidUrl) { - if (!clientSocket.destroyed) { - await clientSocketEnd('HTTP/1.1 400 Bad Request\r\n' + '\r\n'); - clientSocket.destroy(e); + const timer = timerStart(this.connConnectTime); + try { + await this.connectForward( + nodeId, + proxyHost, + proxyPort, + clientSocket, + timer, + ); + } catch (e) { + if (e instanceof networkErrors.ErrorProxyConnectInvalidUrl) { + if (!clientSocket.destroyed) { + await clientSocketEnd('HTTP/1.1 400 Bad Request\r\n' + '\r\n'); + clientSocket.destroy(e); + } + return; } - return; - } - if (e instanceof networkErrors.ErrorConnectionStartTimeout) { - if (!clientSocket.destroyed) { - await clientSocketEnd('HTTP/1.1 504 Gateway Timeout\r\n' + '\r\n'); - clientSocket.destroy(e); + if (e instanceof networkErrors.ErrorConnectionStartTimeout) { + if (!clientSocket.destroyed) { + await clientSocketEnd( + 'HTTP/1.1 504 Gateway Timeout\r\n' + '\r\n', + ); + clientSocket.destroy(e); + } + return; } - return; - } - if (e instanceof networkErrors.ErrorConnectionStart) { - if (!clientSocket.destroyed) { - await clientSocketEnd('HTTP/1.1 502 Bad Gateway\r\n' + '\r\n'); - clientSocket.destroy(e); + if (e instanceof networkErrors.ErrorConnectionStart) { + if (!clientSocket.destroyed) { + await clientSocketEnd('HTTP/1.1 502 Bad Gateway\r\n' + '\r\n'); + clientSocket.destroy(e); + } + return; } - return; - } - if (e instanceof networkErrors.ErrorCertChain) { - if (!clientSocket.destroyed) { - await clientSocketEnd( - 'HTTP/1.1 526 Invalid SSL Certificate\r\n' + '\r\n', - ); - clientSocket.destroy(e); + if (e instanceof networkErrors.ErrorCertChain) { + if (!clientSocket.destroyed) { + await clientSocketEnd( + 'HTTP/1.1 526 Invalid SSL Certificate\r\n' + '\r\n', + ); + clientSocket.destroy(e); + } + return; } - return; - } - if (e instanceof networkErrors.ErrorConnectionTimeout) { - if (!clientSocket.destroyed) { - await clientSocketEnd( - 'HTTP/1.1 524 A Timeout Occurred\r\n' + '\r\n', - ); - clientSocket.destroy(e); + if (e instanceof networkErrors.ErrorConnectionTimeout) { + if (!clientSocket.destroyed) { + await clientSocketEnd( + 'HTTP/1.1 524 A Timeout Occurred\r\n' + '\r\n', + ); + clientSocket.destroy(e); + } + return; + } + if (e instanceof networkErrors.ErrorConnection) { + if (!clientSocket.destroyed) { + await clientSocketEnd( + 'HTTP/1.1 500 Internal Server Error\r\n' + '\r\n', + ); + clientSocket.destroy(e); + } + return; } - return; - } - if (e instanceof networkErrors.ErrorConnection) { if (!clientSocket.destroyed) { await clientSocketEnd( 'HTTP/1.1 500 Internal Server Error\r\n' + '\r\n', @@ -481,27 +492,19 @@ class Proxy { clientSocket.destroy(e); } return; + } finally { + timerStop(timer); } - if (!clientSocket.destroyed) { - await clientSocketEnd( - 'HTTP/1.1 500 Internal Server Error\r\n' + '\r\n', - ); - clientSocket.destroy(e); - } - return; + // After composing, switch off this error handler + clientSocket.off('error', handleConnectError); + await clientSocketWrite( + 'HTTP/1.1 200 Connection Established\r\n' + '\r\n', + ); + this.logger.info(`Handled CONNECT to ${proxyAddress}`); } finally { - timerStop(timer); + this.connectionLocksForward.delete(proxyAddress as Address); } - // After composing, switch off this error handler - clientSocket.off('error', handleConnectError); - await clientSocketWrite( - 'HTTP/1.1 200 Connection Established\r\n' + '\r\n', - ); - this.logger.info(`Handled CONNECT to ${proxyAddress}`); - } finally { - release(); - this.connectionLocksForward.delete(proxyAddress as Address); - } + }); }; protected async connectForward( @@ -590,19 +593,19 @@ class Proxy { const proxyAddress = networkUtils.buildAddress(proxyHost, proxyPort); let lock = this.connectionLocksReverse.get(proxyAddress); if (lock == null) { - lock = new Mutex(); + lock = new Lock(); this.connectionLocksReverse.set(proxyAddress, lock); } - const release = await lock.acquire(); - try { - await this.establishConnectionReverse(proxyHost, proxyPort, timer_); - } finally { - if (timer === undefined) { - timerStop(timer_!); + await withF([lock.lock()], async () => { + try { + await this.establishConnectionReverse(proxyHost, proxyPort, timer_); + } finally { + if (timer === undefined) { + timerStop(timer_!); + } + this.connectionLocksReverse.delete(proxyAddress); } - release(); - this.connectionLocksReverse.delete(proxyAddress); - } + }); } @ready(new networkErrors.ErrorProxyNotRunning(), true) @@ -613,20 +616,20 @@ class Proxy { const proxyAddress = networkUtils.buildAddress(proxyHost, proxyPort); let lock = this.connectionLocksReverse.get(proxyAddress); if (lock == null) { - lock = new Mutex(); + lock = new Lock(); this.connectionLocksReverse.set(proxyAddress, lock); } - const release = await lock.acquire(); - try { - const conn = this.connectionsReverse.proxy.get(proxyAddress); - if (conn == null) { - return; + await withF([lock.lock()], async () => { + try { + const conn = this.connectionsReverse.proxy.get(proxyAddress); + if (conn == null) { + return; + } + await conn.stop(); + } finally { + this.connectionLocksReverse.delete(proxyAddress); } - await conn.stop(); - } finally { - release(); - this.connectionLocksReverse.delete(proxyAddress); - } + }); } protected handleConnectionReverse = async ( @@ -638,38 +641,38 @@ class Proxy { ); let lock = this.connectionLocksReverse.get(proxyAddress); if (lock == null) { - lock = new Mutex(); + lock = new Lock(); this.connectionLocksReverse.set(proxyAddress, lock); } - const release = await lock.acquire(); - try { - this.logger.info(`Handling connection from ${proxyAddress}`); - const timer = timerStart(this.connConnectTime); + await withF([lock.lock()], async () => { try { - await this.connectReverse( - utpConn.remoteAddress, - utpConn.remotePort, - utpConn, - timer, - ); - } catch (e) { - if (!(e instanceof networkErrors.ErrorNetwork)) { - throw e; - } - if (!utpConn.destroyed) { - utpConn.destroy(); + this.logger.info(`Handling connection from ${proxyAddress}`); + const timer = timerStart(this.connConnectTime); + try { + await this.connectReverse( + utpConn.remoteAddress, + utpConn.remotePort, + utpConn, + timer, + ); + } catch (e) { + if (!(e instanceof networkErrors.ErrorNetwork)) { + throw e; + } + if (!utpConn.destroyed) { + utpConn.destroy(); + } + this.logger.warn( + `Failed connection from ${proxyAddress} - ${e.toString()}`, + ); + } finally { + timerStop(timer); } - this.logger.warn( - `Failed connection from ${proxyAddress} - ${e.toString()}`, - ); + this.logger.info(`Handled connection from ${proxyAddress}`); } finally { - timerStop(timer); + this.connectionLocksReverse.delete(proxyAddress); } - this.logger.info(`Handled connection from ${proxyAddress}`); - } finally { - release(); - this.connectionLocksReverse.delete(proxyAddress); - } + }); }; protected async connectReverse( diff --git a/src/network/errors.ts b/src/network/errors.ts index 234f90a22..e8189010c 100644 --- a/src/network/errors.ts +++ b/src/network/errors.ts @@ -1,128 +1,132 @@ import { ErrorPolykey, sysexits } from '../errors'; -class ErrorNetwork extends ErrorPolykey {} +class ErrorNetwork extends ErrorPolykey {} -class ErrorProxy extends ErrorNetwork {} +class ErrorProxy extends ErrorNetwork {} -class ErrorProxyNotRunning extends ErrorProxy { - description = 'Proxy is not running'; +class ErrorProxyNotRunning extends ErrorProxy { + static description = 'Proxy is not running'; exitCode = sysexits.USAGE; } -class ErrorProxyConnectInvalidUrl extends ErrorProxy { - description = 'Invalid target host used for HTTP connect proxy'; +class ErrorProxyConnectInvalidUrl extends ErrorProxy { + static description = 'Invalid target host used for HTTP connect proxy'; exitCode = sysexits.PROTOCOL; } -class ErrorProxyConnectMissingNodeId extends ErrorProxy { - description = 'Node ID query parameter is required for HTTP connect proxy'; +class ErrorProxyConnectMissingNodeId extends ErrorProxy { + static description = + 'Node ID query parameter is required for HTTP connect proxy'; exitCode = sysexits.PROTOCOL; } -class ErrorProxyConnectAuth extends ErrorProxy { - description = 'Incorrect HTTP connect proxy password'; +class ErrorProxyConnectAuth extends ErrorProxy { + static description = 'Incorrect HTTP connect proxy password'; exitCode = sysexits.NOPERM; } -class ErrorConnection extends ErrorNetwork {} +class ErrorConnection extends ErrorNetwork {} -class ErrorConnectionNotRunning extends ErrorConnection { - description = 'Connection is not running'; +class ErrorConnectionNotRunning extends ErrorConnection { + static description = 'Connection is not running'; exitCode = sysexits.USAGE; } -class ErrorConnectionComposed extends ErrorConnection { - description = 'Connection is composed'; +class ErrorConnectionComposed extends ErrorConnection { + static description = 'Connection is composed'; exitCode = sysexits.USAGE; } -class ErrorConnectionNotComposed extends ErrorConnection { - description = 'Connection is not composed'; +class ErrorConnectionNotComposed extends ErrorConnection { + static description = 'Connection is not composed'; exitCode = sysexits.USAGE; } -class ErrorConnectionMessageParse extends ErrorConnection { - description = 'Network message received is invalid'; +class ErrorConnectionMessageParse extends ErrorConnection { + static description = 'Network message received is invalid'; exitCode = sysexits.TEMPFAIL; } -class ErrorConnectionTimeout extends ErrorConnection { - description = 'Connection keep-alive timed out'; +class ErrorConnectionTimeout extends ErrorConnection { + static description = 'Connection keep-alive timed out'; exitCode = sysexits.UNAVAILABLE; } -class ErrorConnectionEndTimeout extends ErrorConnection { - description = 'Connection end timed out'; +class ErrorConnectionEndTimeout extends ErrorConnection { + static description = 'Connection end timed out'; exitCode = sysexits.UNAVAILABLE; } /** * Used by ConnectionForward and ConnectionReverse */ -class ErrorConnectionStart extends ErrorConnection { - description = 'Connection start failed'; +class ErrorConnectionStart extends ErrorConnection { + static description = 'Connection start failed'; exitCode = sysexits.PROTOCOL; } -class ErrorConnectionStartTimeout extends ErrorConnectionStart { - description = 'Connection start timed out'; +class ErrorConnectionStartTimeout extends ErrorConnectionStart { + static description = 'Connection start timed out'; exitCode = sysexits.NOHOST; } /** * Used by ConnectionReverse */ -class ErrorConnectionCompose extends ErrorConnection { - description = 'Connection compose failed'; +class ErrorConnectionCompose extends ErrorConnection { + static description = 'Connection compose failed'; exitCode = sysexits.PROTOCOL; } -class ErrorConnectionComposeTimeout extends ErrorConnectionCompose { - description = 'Connection compose timed out'; +class ErrorConnectionComposeTimeout extends ErrorConnectionCompose { + static description = 'Connection compose timed out'; exitCode = sysexits.NOHOST; } /** * Used for certificate verification */ -class ErrorCertChain extends ErrorNetwork {} +class ErrorCertChain extends ErrorNetwork {} -class ErrorCertChainEmpty extends ErrorCertChain { - description = 'Certificate chain is empty'; +class ErrorCertChainEmpty extends ErrorCertChain { + static description = 'Certificate chain is empty'; exitCode = sysexits.PROTOCOL; } -class ErrorCertChainUnclaimed extends ErrorCertChain { - description = 'The target node id is not claimed by any certificate'; +class ErrorCertChainUnclaimed extends ErrorCertChain { + static description = 'The target node id is not claimed by any certificate'; exitCode = sysexits.PROTOCOL; } -class ErrorCertChainBroken extends ErrorCertChain { - description = 'The signature chain is broken'; +class ErrorCertChainBroken extends ErrorCertChain { + static description = 'The signature chain is broken'; exitCode = sysexits.PROTOCOL; } -class ErrorCertChainDateInvalid extends ErrorCertChain { - description = 'Certificate in the chain is expired'; +class ErrorCertChainDateInvalid extends ErrorCertChain { + static description = 'Certificate in the chain is expired'; exitCode = sysexits.PROTOCOL; } -class ErrorCertChainNameInvalid extends ErrorCertChain { - description = 'Certificate is missing the common name'; +class ErrorCertChainNameInvalid extends ErrorCertChain { + static description = 'Certificate is missing the common name'; exitCode = sysexits.PROTOCOL; } -class ErrorCertChainKeyInvalid extends ErrorCertChain { - description = 'Certificate public key does not generate the Node ID'; +class ErrorCertChainKeyInvalid extends ErrorCertChain { + static description = 'Certificate public key does not generate the Node ID'; exitCode = sysexits.PROTOCOL; } -class ErrorCertChainSignatureInvalid extends ErrorCertChain { - description = 'Certificate self-signed signature is invalid'; +class ErrorCertChainSignatureInvalid extends ErrorCertChain { + static description = 'Certificate self-signed signature is invalid'; exitCode = sysexits.PROTOCOL; } -class ErrorHostnameResolutionFailed extends ErrorNetwork {} +class ErrorHostnameResolutionFailed extends ErrorNetwork { + static description = 'Unable to resolve hostname'; + exitCode = sysexits.USAGE; +} export { ErrorNetwork, diff --git a/src/network/utils.ts b/src/network/utils.ts index 8347da631..1df7faa7f 100644 --- a/src/network/utils.ts +++ b/src/network/utils.ts @@ -101,7 +101,9 @@ async function resolveHost(host: Host | Hostname): Promise { // Resolve the hostname and get the IPv4 address resolvedHost = await lookup(host, 4); } catch (e) { - throw new networkErrors.ErrorHostnameResolutionFailed(e.message); + throw new networkErrors.ErrorHostnameResolutionFailed(e.message, { + cause: e, + }); } // Returns an array of [ resolved address, family (4 or 6) ] return resolvedHost[0] as Host; @@ -201,11 +203,13 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainDateInvalid( 'Chain certificate date is invalid', { - cert, - certIndex, - notBefore: cert.validity.notBefore, - notAfter: cert.validity.notAfter, - now, + data: { + cert, + certIndex, + notBefore: cert.validity.notBefore, + notAfter: cert.validity.notAfter, + now, + }, }, ); } @@ -214,8 +218,10 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainNameInvalid( 'Chain certificate common name attribute is missing', { - cert, - certIndex, + data: { + cert, + certIndex, + }, }, ); } @@ -224,10 +230,12 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainKeyInvalid( 'Chain certificate public key does not generate its node id', { - cert, - certIndex, - nodeId: certNodeId, - commonName: commonName.value, + data: { + cert, + certIndex, + nodeId: certNodeId, + commonName: commonName.value, + }, }, ); } @@ -235,8 +243,10 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainSignatureInvalid( 'Chain certificate does not have a valid node-signature', { - cert, - certIndex, + data: { + cert, + certIndex, + }, }, ); } @@ -251,7 +261,7 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainUnclaimed( 'Node ID is not claimed by any certificate', { - nodeId, + data: { nodeId }, }, ); } @@ -268,9 +278,11 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainBroken( 'Chain certificate is not signed by parent certificate', { - cert: certChild, - certIndex: certIndex - 1, - certParent, + data: { + cert: certChild, + certIndex: certIndex - 1, + certParent, + }, }, ); } @@ -296,11 +308,13 @@ function verifyClientCertificateChain(certChain: Array): void { throw new networkErrors.ErrorCertChainDateInvalid( 'Chain certificate date is invalid', { - cert, - certIndex, - notBefore: cert.validity.notBefore, - notAfter: cert.validity.notAfter, - now, + data: { + cert, + certIndex, + notBefore: cert.validity.notBefore, + notAfter: cert.validity.notAfter, + now, + }, }, ); } @@ -309,8 +323,10 @@ function verifyClientCertificateChain(certChain: Array): void { throw new networkErrors.ErrorCertChainNameInvalid( 'Chain certificate common name attribute is missing', { - cert, - certIndex, + data: { + cert, + certIndex, + }, }, ); } @@ -319,10 +335,12 @@ function verifyClientCertificateChain(certChain: Array): void { throw new networkErrors.ErrorCertChainKeyInvalid( 'Chain certificate public key does not generate its node id', { - cert, - certIndex, - nodeId: certNodeId, - commonName: commonName.value, + data: { + cert, + certIndex, + nodeId: certNodeId, + commonName: commonName.value, + }, }, ); } @@ -330,8 +348,10 @@ function verifyClientCertificateChain(certChain: Array): void { throw new networkErrors.ErrorCertChainSignatureInvalid( 'Chain certificate does not have a valid node-signature', { - cert, - certIndex, + data: { + cert, + certIndex, + }, }, ); } @@ -343,9 +363,11 @@ function verifyClientCertificateChain(certChain: Array): void { throw new networkErrors.ErrorCertChainSignatureInvalid( 'Chain certificate is not signed by parent certificate', { - cert, - certIndex, - certParent: certNext, + data: { + cert, + certIndex, + certParent: certNext, + }, }, ); } diff --git a/src/nodes/NodeConnection.ts b/src/nodes/NodeConnection.ts index 6788c20fe..f79272413 100644 --- a/src/nodes/NodeConnection.ts +++ b/src/nodes/NodeConnection.ts @@ -135,7 +135,9 @@ class NodeConnection { await nodeConnection.destroy(); // If the connection times out, re-throw this with a higher level nodes exception if (e instanceof grpcErrors.ErrorGRPCClientTimeout) { - throw new nodesErrors.ErrorNodeConnectionTimeout(); + throw new nodesErrors.ErrorNodeConnectionTimeout(e.message, { + cause: e, + }); } throw e; } diff --git a/src/nodes/NodeConnectionManager.ts b/src/nodes/NodeConnectionManager.ts index 6160aa60a..9f7632d2f 100644 --- a/src/nodes/NodeConnectionManager.ts +++ b/src/nodes/NodeConnectionManager.ts @@ -1,7 +1,7 @@ +import type { ResourceAcquire } from '@matrixai/resources'; import type KeyManager from '../keys/KeyManager'; import type Proxy from '../network/Proxy'; import type { Host, Hostname, Port } from '../network/types'; -import type { ResourceAcquire } from '../utils'; import type { Timer } from '../types'; import type NodeGraph from './NodeGraph'; import type { @@ -11,10 +11,13 @@ import type { SeedNodes, NodeIdString, } from './types'; +import type { DBTransaction } from '@matrixai/db'; import Logger from '@matrixai/logger'; import { StartStop, ready } from '@matrixai/async-init/dist/StartStop'; import { IdInternal } from '@matrixai/id'; import { status } from '@matrixai/async-init'; +import { withF } from '@matrixai/resources'; +import { RWLockWriter } from '@matrixai/async-locks'; import NodeConnection from './NodeConnection'; import * as nodesUtils from './utils'; import * as nodesErrors from './errors'; @@ -24,12 +27,11 @@ import * as networkUtils from '../network/utils'; import * as agentErrors from '../agent/errors'; import * as grpcErrors from '../grpc/errors'; import * as nodesPB from '../proto/js/polykey/v1/nodes/nodes_pb'; -import { RWLock, withF } from '../utils'; type ConnectionAndLock = { connection?: NodeConnection; timer?: NodeJS.Timer; - lock: RWLock; + lock: RWLockWriter; }; interface NodeConnectionManager extends StartStop {} @@ -131,13 +133,21 @@ class NodeConnectionManager { return async () => { const connAndLock = await this.getConnection(targetNodeId); // Acquire the read lock and the release function - const release = await connAndLock.lock.acquireRead(); + const [release] = await connAndLock.lock.read()(); // Resetting TTL timer connAndLock.timer?.refresh(); // Return tuple of [ResourceRelease, Resource] return [ - async () => { - release(); + async (e) => { + await release(); + if ( + e instanceof nodesErrors.ErrorNodeConnectionDestroyed || + e instanceof grpcErrors.ErrorGRPC || + e instanceof agentErrors.ErrorAgentClientDestroyed + ) { + // Error with connection, shutting connection down + await this.destroyConnection(targetNodeId); + } }, connAndLock.connection, ]; @@ -157,29 +167,17 @@ class NodeConnectionManager { targetNodeId: NodeId, f: (conn: NodeConnection) => Promise, ): Promise { - try { - return await withF( - [await this.acquireConnection(targetNodeId)], - async ([conn]) => { - this.logger.info( - `withConnF calling function with connection to ${nodesUtils.encodeNodeId( - targetNodeId, - )}`, - ); - return await f(conn); - }, - ); - } catch (err) { - if ( - err instanceof nodesErrors.ErrorNodeConnectionDestroyed || - err instanceof grpcErrors.ErrorGRPC || - err instanceof agentErrors.ErrorAgentClientDestroyed - ) { - // Error with connection, shutting connection down - await this.destroyConnection(targetNodeId); - } - throw err; - } + return await withF( + [await this.acquireConnection(targetNodeId)], + async ([conn]) => { + this.logger.info( + `withConnF calling function with connection to ${nodesUtils.encodeNodeId( + targetNodeId, + )}`, + ); + return await f(conn); + }, + ); } /** @@ -199,21 +197,14 @@ class NodeConnectionManager { ): AsyncGenerator { const acquire = await this.acquireConnection(targetNodeId); const [release, conn] = await acquire(); + let caughtError; try { return yield* await g(conn!); - } catch (err) { - if ( - err instanceof nodesErrors.ErrorNodeConnectionDestroyed || - err instanceof grpcErrors.ErrorGRPC || - err instanceof agentErrors.ErrorAgentClientDestroyed - ) { - // Error with connection, shutting connection down - await release(); - await this.destroyConnection(targetNodeId); - } - throw err; + } catch (e) { + caughtError = e; + throw e; } finally { - await release(); + await release(caughtError); } // Wait for any destruction to complete after locking is removed } @@ -231,7 +222,7 @@ class NodeConnectionManager { `Getting connection to ${nodesUtils.encodeNodeId(targetNodeId)}`, ); let connection: NodeConnection | undefined; - let lock: RWLock; + let lock: RWLockWriter; let connAndLock = this.connections.get( targetNodeId.toString() as NodeIdString, ); @@ -240,7 +231,7 @@ class NodeConnectionManager { // Connection already exists, so return if (connection != null) return connAndLock; // Acquire the write (creation) lock - return await lock.withWrite(async () => { + return await lock.withWriteF(async () => { // Once lock is released, check again if the conn now exists connAndLock = this.connections.get( targetNodeId.toString() as NodeIdString, @@ -260,13 +251,13 @@ class NodeConnectionManager { return await this.establishNodeConnection(targetNodeId, lock); }); } else { - lock = new RWLock(); + lock = new RWLockWriter(); connAndLock = { lock }; this.connections.set( targetNodeId.toString() as NodeIdString, connAndLock, ); - return await lock.withWrite(async () => { + return await lock.withWriteF(async () => { this.logger.info( `no existing entry, creating connection to ${nodesUtils.encodeNodeId( targetNodeId, @@ -290,7 +281,7 @@ class NodeConnectionManager { */ protected async establishNodeConnection( targetNodeId: NodeId, - lock: RWLock, + lock: RWLockWriter, ): Promise { const targetAddress = await this.findNode(targetNodeId); // If the stored host is not a valid host (IP address), then we assume it to @@ -308,7 +299,7 @@ class NodeConnectionManager { ); // If the connection is calling destroyCallback then it SHOULD // exist in the connection map - if (connAndLock == null) throw Error('temp error, bad logic'); + if (connAndLock == null) throw Error('temp eor, bad logic'); // Already locked so already destroying if (connAndLock.lock.readerCount > 0) return; const connectionStatus = connAndLock?.connection?.[status]; @@ -359,7 +350,7 @@ class NodeConnectionManager { const lock = connAndLock.lock; // If the connection exists then we lock, destroy and remove it from the map - await lock.withWrite(async () => { + await lock.withWriteF(async () => { // Destroying connection await connection.destroy(); // Destroying TTL timer @@ -447,6 +438,7 @@ class NodeConnectionManager { * @param targetNodeId the node ID to find other nodes closest to it * @param numClosest the number of closest nodes to return (by default, returns * according to the maximum number of nodes per bucket) + * @param tran * @returns a mapping containing exactly k nodeIds -> nodeAddresses (unless the * current node has less than k nodes in all of its buckets, in which case it * returns all nodes it has knowledge of) @@ -455,9 +447,10 @@ class NodeConnectionManager { public async getClosestLocalNodes( targetNodeId: NodeId, numClosest: number = this.nodeGraph.maxNodesPerBucket, + tran?: DBTransaction, ): Promise> { // Retrieve all nodes from buckets in database - const buckets = await this.nodeGraph.getAllBuckets(); + const buckets = await this.nodeGraph.getAllBuckets(tran); // Iterate over all of the nodes in each bucket const distanceToNodes: Array = []; buckets.forEach(function (bucket) { @@ -503,7 +496,7 @@ class NodeConnectionManager { this.initialClosestNodes, ); // If we have no nodes at all in our database (even after synchronising), - // then we should throw an error. We aren't going to find any others + // then we should throw an eor. We aren't going to find any others if (shortlist.length === 0) { throw new nodesErrors.ErrorNodeGraphEmptyDatabase(); } diff --git a/src/nodes/NodeGraph.ts b/src/nodes/NodeGraph.ts index 4237b5529..ddf2ff7b3 100644 --- a/src/nodes/NodeGraph.ts +++ b/src/nodes/NodeGraph.ts @@ -1,8 +1,7 @@ -import type { DB, DBLevel, DBOp } from '@matrixai/db'; +import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { NodeId, NodeAddress, NodeBucket } from './types'; import type KeyManager from '../keys/KeyManager'; import type { Host, Hostname, Port } from '../network/types'; -import { Mutex } from 'async-mutex'; import lexi from 'lexicographic-integer'; import Logger from '@matrixai/logger'; import { @@ -10,6 +9,8 @@ import { ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { IdInternal } from '@matrixai/id'; +import { utils as dbUtils } from '@matrixai/db'; +import { withF } from '@matrixai/resources'; import * as nodesUtils from './utils'; import * as nodesErrors from './errors'; @@ -23,21 +24,6 @@ interface NodeGraph extends CreateDestroyStartStop {} new nodesErrors.ErrorNodeGraphDestroyed(), ) class NodeGraph { - // Max number of nodes in each k-bucket (a.k.a. k) - public readonly maxNodesPerBucket: number = 20; - - protected logger: Logger; - protected db: DB; - protected keyManager: KeyManager; - protected nodeGraphDbDomain: string = this.constructor.name; - protected nodeGraphBucketsDbDomain: Array = [ - this.nodeGraphDbDomain, - 'buckets', - ]; - protected nodeGraphDb: DBLevel; - protected nodeGraphBucketsDb: DBLevel; - protected lock: Mutex = new Mutex(); - public static async createNodeGraph({ db, keyManager, @@ -60,6 +46,23 @@ class NodeGraph { return nodeGraph; } + /** + * Max number of nodes in each k-bucket (a.k.a. k) + */ + public readonly maxNodesPerBucket: number = 20; + + protected logger: Logger; + protected db: DB; + protected keyManager: KeyManager; + protected nodeGraphDbPath: LevelPath = [this.constructor.name]; + /** + * Buckets stores NodeBucketIndex -> NodeBucket + */ + protected nodeGraphBucketsDbPath: LevelPath = [ + this.constructor.name, + 'buckets', + ]; + constructor({ db, keyManager, @@ -74,27 +77,15 @@ class NodeGraph { this.keyManager = keyManager; } - get locked(): boolean { - return this.lock.isLocked(); - } - public async start({ fresh = false, }: { fresh?: boolean; } = {}) { this.logger.info(`Starting ${this.constructor.name}`); - const nodeGraphDb = await this.db.level(this.nodeGraphDbDomain); - // Buckets stores NodeBucketIndex -> NodeBucket - const nodeGraphBucketsDb = await this.db.level( - this.nodeGraphBucketsDbDomain[1], - nodeGraphDb, - ); if (fresh) { - await nodeGraphDb.clear(); + await this.db.clear(this.nodeGraphDbPath); } - this.nodeGraphDb = nodeGraphDb; - this.nodeGraphBucketsDb = nodeGraphBucketsDb; this.logger.info(`Started ${this.constructor.name}`); } @@ -105,117 +96,109 @@ class NodeGraph { public async destroy() { this.logger.info(`Destroying ${this.constructor.name}`); - const nodeGraphDb = await this.db.level(this.nodeGraphDbDomain); - await nodeGraphDb.clear(); + await this.db.clear(this.nodeGraphDbPath); this.logger.info(`Destroyed ${this.constructor.name}`); } - /** - * Run several operations within the same lock - * This does not ensure atomicity of the underlying database - * Database atomicity still depends on the underlying operation - */ - public async transaction( - f: (nodeGraph: NodeGraph) => Promise, + @ready(new nodesErrors.ErrorNodeGraphNotRunning()) + public async withTransactionF( + f: (tran: DBTransaction) => Promise, ): Promise { - const release = await this.lock.acquire(); - try { - return await f(this); - } finally { - release(); - } - } - - /** - * Transaction wrapper that will not lock if the operation was executed - * within a transaction context - */ - public async _transaction(f: () => Promise): Promise { - if (this.lock.isLocked()) { - return await f(); - } else { - return await this.transaction(f); - } + return withF([this.db.transaction()], ([tran]) => f(tran)); } /** * Retrieves the node Address * @param nodeId node ID of the target node + * @param tran * @returns Node Address of the target node */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) - public async getNode(nodeId: NodeId): Promise { - return await this._transaction(async () => { - const bucketIndex = this.getBucketIndex(nodeId); - const bucket = await this.db.get( - this.nodeGraphBucketsDbDomain, - bucketIndex, - ); - if (bucket != null && nodeId in bucket) { - return bucket[nodeId].address; - } - return; - }); + public async getNode( + nodeId: NodeId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => this.getNode(nodeId, tran)); + } + const bucketIndex = this.getBucketIndex(nodeId); + const bucketPath = [ + ...this.nodeGraphBucketsDbPath, + bucketIndex, + ] as unknown as KeyPath; + const bucket = await tran.get(bucketPath); + if (bucket != null && nodeId in bucket) { + return bucket[nodeId].address; + } + return; } /** * Determines whether a node ID -> node address mapping exists in this node's * node table. * @param targetNodeId the node ID of the node to find + * @param tran * @returns true if the node exists in the table, false otherwise */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) - public async knowsNode(targetNodeId: NodeId): Promise { - return !!(await this.getNode(targetNodeId)); + public async knowsNode( + targetNodeId: NodeId, + tran?: DBTransaction, + ): Promise { + return !!(await this.getNode(targetNodeId, tran)); } /** * Returns the specified bucket if it exists * @param bucketIndex + * @param tran */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) - public async getBucket(bucketIndex: number): Promise { - return await this._transaction(async () => { - const bucket = await this.db.get( - this.nodeGraphBucketsDbDomain, - lexi.pack(bucketIndex, 'hex'), + public async getBucket( + bucketIndex: number, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getBucket(bucketIndex, tran), ); - // Cast the non-primitive types correctly (ensures type safety when using them) - for (const nodeId in bucket) { - bucket[nodeId].address.host = bucket[nodeId].address.host as - | Host - | Hostname; - bucket[nodeId].address.port = bucket[nodeId].address.port as Port; - bucket[nodeId].lastUpdated = new Date(bucket[nodeId].lastUpdated); - } - return bucket; - }); + } + const bucketPath = [ + ...this.nodeGraphBucketsDbPath, + lexi.pack(bucketIndex, 'hex'), + ] as unknown as KeyPath; + const bucket = await tran.get(bucketPath); + // Cast the non-primitive types correctly (ensures type safety when using them) + for (const nodeId in bucket) { + bucket[nodeId].address.host = bucket[nodeId].address.host as + | Host + | Hostname; + bucket[nodeId].address.port = bucket[nodeId].address.port as Port; + bucket[nodeId].lastUpdated = new Date(bucket[nodeId].lastUpdated); + } + return bucket; } /** * Sets a node to the bucket database * This may delete an existing node if the bucket is filled up */ - @ready(new nodesErrors.ErrorNodeGraphNotRunning()) public async setNode( nodeId: NodeId, nodeAddress: NodeAddress, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const ops = await this.setNodeOps(nodeId, nodeAddress); - await this.db.batch(ops); - }); - } - - protected async setNodeOps( - nodeId: NodeId, - nodeAddress: NodeAddress, - ): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.setNode(nodeId, nodeAddress, tran), + ); + } const bucketIndex = this.getBucketIndex(nodeId); - let bucket = await this.db.get( - this.nodeGraphBucketsDbDomain, + const bucketPath = [ + ...this.nodeGraphBucketsDbPath, bucketIndex, - ); + ] as unknown as KeyPath; + let bucket = await tran.get(bucketPath); if (bucket == null) { bucket = {}; } @@ -239,14 +222,7 @@ class NodeGraph { throw new nodesErrors.ErrorNodeGraphOversizedBucket(); } } - return [ - { - type: 'put', - domain: this.nodeGraphBucketsDbDomain, - key: bucketIndex, - value: bucket, - }, - ]; + await tran.put(bucketPath, bucket); } /** @@ -258,78 +234,57 @@ class NodeGraph { public async updateNode( nodeId: NodeId, nodeAddress?: NodeAddress, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const ops = await this.updateNodeOps(nodeId, nodeAddress); - await this.db.batch(ops); - }); - } - - protected async updateNodeOps( - nodeId: NodeId, - nodeAddress?: NodeAddress, - ): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.updateNode(nodeId, nodeAddress, tran), + ); + } const bucketIndex = this.getBucketIndex(nodeId); - const bucket = await this.db.get( - this.nodeGraphBucketsDbDomain, + const bucketPath = [ + ...this.nodeGraphBucketsDbPath, bucketIndex, - ); - const ops: Array = []; + ] as unknown as KeyPath; + const bucket = await tran.get(bucketPath); if (bucket != null && nodeId in bucket) { bucket[nodeId].lastUpdated = new Date(); if (nodeAddress != null) { bucket[nodeId].address = nodeAddress; } - ops.push({ - type: 'put', - domain: this.nodeGraphBucketsDbDomain, - key: bucketIndex, - value: bucket, - }); + await tran.put(bucketPath, bucket); } else { throw new nodesErrors.ErrorNodeGraphNodeIdNotFound(); } - return ops; } /** * Removes a node from the bucket database * @param nodeId + * @param tran */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) - public async unsetNode(nodeId: NodeId): Promise { - return await this._transaction(async () => { - const ops = await this.unsetNodeOps(nodeId); - await this.db.batch(ops); - }); - } - - protected async unsetNodeOps(nodeId: NodeId): Promise> { + public async unsetNode(nodeId: NodeId, tran?: DBTransaction): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.unsetNode(nodeId, tran), + ); + } const bucketIndex = this.getBucketIndex(nodeId); - const bucket = await this.db.get( - this.nodeGraphBucketsDbDomain, + const bucketPath = [ + ...this.nodeGraphBucketsDbPath, bucketIndex, - ); - const ops: Array = []; + ] as unknown as KeyPath; + const bucket = await tran.get(bucketPath); if (bucket == null) { - return ops; + return; } delete bucket[nodeId]; if (Object.keys(bucket).length === 0) { - ops.push({ - type: 'del', - domain: this.nodeGraphBucketsDbDomain, - key: bucketIndex, - }); + await tran.del(bucketPath); } else { - ops.push({ - type: 'put', - domain: this.nodeGraphBucketsDbDomain, - key: bucketIndex, - value: bucket, - }); + await tran.put(bucketPath, bucket); } - return ops; } /** @@ -349,19 +304,18 @@ class NodeGraph { * Returns all of the buckets in an array */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) - public async getAllBuckets(): Promise> { - return await this._transaction(async () => { - const buckets: Array = []; - for await (const o of this.nodeGraphBucketsDb.createReadStream()) { - const data = (o as any).value as Buffer; - const bucket = await this.db.deserializeDecrypt( - data, - false, - ); - buckets.push(bucket); - } - return buckets; - }); + public async getAllBuckets(tran?: DBTransaction): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => this.getAllBuckets(tran)); + } + const buckets: Array = []; + for await (const [, v] of tran.iterator({ keys: false }, [ + ...this.nodeGraphBucketsDbPath, + ])) { + const bucket = dbUtils.deserialize(v); + buckets.push(bucket); + } + return buckets; } /** @@ -372,63 +326,63 @@ class NodeGraph { * will be removed. */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) - public async refreshBuckets(): Promise { - return await this._transaction(async () => { - const ops: Array = []; - // Get a local copy of all the buckets - const buckets = await this.getAllBuckets(); - // Wrap as a batch operation. We want to rollback if we encounter any - // errors (such that we don't clear the DB without re-adding the nodes) - // 1. Delete every bucket - for await (const k of this.nodeGraphBucketsDb.createKeyStream()) { - const hexBucketIndex = k as string; - ops.push({ - type: 'del', - domain: this.nodeGraphBucketsDbDomain, - key: hexBucketIndex, - }); - } - const tempBuckets: Record = {}; - // 2. Re-add all the nodes from all buckets - for (const b of buckets) { - for (const n of Object.keys(b)) { - const nodeId = IdInternal.fromString(n); - const newIndex = this.getBucketIndex(nodeId); - let expectedBucket = tempBuckets[newIndex]; - // The following is more or less copied from setNodeOps - if (expectedBucket == null) { - expectedBucket = {}; - } - const bucketEntries = Object.entries(expectedBucket); - // Add the old node - expectedBucket[nodeId] = { - address: b[nodeId].address, - lastUpdated: b[nodeId].lastUpdated, - }; - // If, with the old node added, we exceed the limit - if (bucketEntries.length > this.maxNodesPerBucket) { - // Then, with the old node added, find the least active and remove - const leastActive = bucketEntries.reduce((prev, curr) => { - return prev[1].lastUpdated < curr[1].lastUpdated ? prev : curr; - }); - delete expectedBucket[leastActive[0]]; - } - // Add this reconstructed bucket (with old node) into the temp storage - tempBuckets[newIndex] = expectedBucket; + public async refreshBuckets(tran?: DBTransaction): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => this.refreshBuckets(tran)); + } + // Get a local copy of all the buckets + const buckets = await this.getAllBuckets(tran); + // Wrap as a batch operation. We want to rollback if we encounter any + // errors (such that we don't clear the DB without re-adding the nodes) + // 1. Delete every bucket + for await (const [k] of tran.iterator({ value: false }, [ + ...this.nodeGraphBucketsDbPath, + ])) { + const hexBucketIndex = k.toString(); + const hexBucketPath = [ + ...this.nodeGraphBucketsDbPath, + hexBucketIndex, + ] as unknown as KeyPath; + await tran.del(hexBucketPath); + } + const tempBuckets: Record = {}; + // 2. Re-add all the nodes from all buckets + for (const b of buckets) { + for (const n of Object.keys(b)) { + const nodeId = IdInternal.fromString(n); + const newIndex = this.getBucketIndex(nodeId); + let expectedBucket = tempBuckets[newIndex]; + // The following is more or less copied from setNodeOps + if (expectedBucket == null) { + expectedBucket = {}; } + const bucketEntries = Object.entries(expectedBucket); + // Add the old node + expectedBucket[nodeId] = { + address: b[nodeId].address, + lastUpdated: b[nodeId].lastUpdated, + }; + // If, with the old node added, we exceed the limit + if (bucketEntries.length > this.maxNodesPerBucket) { + // Then, with the old node added, find the least active and remove + const leastActive = bucketEntries.reduce((prev, curr) => { + return prev[1].lastUpdated < curr[1].lastUpdated ? prev : curr; + }); + delete expectedBucket[leastActive[0]]; + } + // Add this reconstructed bucket (with old node) into the temp storage + tempBuckets[newIndex] = expectedBucket; } - // Now that we've reconstructed all the buckets, perform batch operations - // on a bucket level (i.e. per bucket, instead of per node) - for (const bucketIndex in tempBuckets) { - ops.push({ - type: 'put', - domain: this.nodeGraphBucketsDbDomain, - key: bucketIndex, - value: tempBuckets[bucketIndex], - }); - } - await this.db.batch(ops); - }); + } + // Now that we've reconstructed all the buckets, perform batch operations + // on a bucket level (i.e. per bucket, instead of per node) + for (const bucketIndex in tempBuckets) { + const bucketPath = [ + ...this.nodeGraphBucketsDbPath, + bucketIndex, + ] as unknown as KeyPath; + await tran.put(bucketPath, tempBuckets[bucketIndex]); + } } } diff --git a/src/nodes/NodeManager.ts b/src/nodes/NodeManager.ts index b28343667..6adf77867 100644 --- a/src/nodes/NodeManager.ts +++ b/src/nodes/NodeManager.ts @@ -1,4 +1,4 @@ -import type { DB } from '@matrixai/db'; +import type { DB, DBTransaction } from '@matrixai/db'; import type NodeConnectionManager from './NodeConnectionManager'; import type NodeGraph from './NodeGraph'; import type KeyManager from '../keys/KeyManager'; @@ -10,7 +10,7 @@ import type { ClaimEncoded } from '../claims/types'; import Logger from '@matrixai/logger'; import * as nodesErrors from './errors'; import * as nodesUtils from './utils'; -import { utils as validationUtils } from '../validation'; +import * as validationUtils from '../validation/utils'; import * as utilsPB from '../proto/js/polykey/v1/utils/utils_pb'; import * as claimsErrors from '../claims/errors'; import * as networkErrors from '../network/errors'; @@ -182,147 +182,161 @@ class NodeManager { * Call this function upon receiving a "claim node request" notification from * another node. */ - public async claimNode(targetNodeId: NodeId): Promise { - await this.sigchain.transaction(async (sigchain) => { - // 2. Create your intermediary claim - const singlySignedClaim = await sigchain.createIntermediaryClaim({ + public async claimNode( + targetNodeId: NodeId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => { + return this.claimNode(targetNodeId, tran); + }); + } + + // 2. Create your intermediary claim + const singlySignedClaim = await this.sigchain.createIntermediaryClaim( + { type: 'node', node1: nodesUtils.encodeNodeId(this.keyManager.getNodeId()), node2: nodesUtils.encodeNodeId(targetNodeId), - }); - let doublySignedClaim: ClaimEncoded; - await this.nodeConnectionManager.withConnF( - targetNodeId, - async (connection) => { - const client = connection.getClient(); - const genClaims = client.nodesCrossSignClaim(); - try { - // 2. Set up the intermediary claim message (the singly signed claim) to send - const crossSignMessage = claimsUtils.createCrossSignMessage({ - singlySignedClaim: singlySignedClaim, - }); - await genClaims.write(crossSignMessage); // Get the generator here - // 3. We expect to receieve our singly signed claim we sent to now be a - // doubly signed claim (signed by the other node), as well as a singly - // signed claim to be signed by us - const readStatus = await genClaims.read(); - // If nothing to read, end and destroy - if (readStatus.done) { - throw new claimsErrors.ErrorEmptyStream(); - } - const receivedMessage = readStatus.value; - const intermediaryClaimMessage = - receivedMessage.getSinglySignedClaim(); - const doublySignedClaimMessage = - receivedMessage.getDoublySignedClaim(); - // Ensure all of our expected messages are defined - if (!intermediaryClaimMessage) { - throw new claimsErrors.ErrorUndefinedSinglySignedClaim(); - } - const intermediaryClaimSignature = - intermediaryClaimMessage.getSignature(); - if (!intermediaryClaimSignature) { - throw new claimsErrors.ErrorUndefinedSignature(); - } - if (!doublySignedClaimMessage) { - throw new claimsErrors.ErrorUndefinedDoublySignedClaim(); - } - // Reconstruct the expected objects from the messages - const constructedIntermediaryClaim = - claimsUtils.reconstructClaimIntermediary( - intermediaryClaimMessage, - ); - const constructedDoublySignedClaim = - claimsUtils.reconstructClaimEncoded(doublySignedClaimMessage); - // Verify the singly signed claim with the sender's public key - const senderPublicKey = - connection.getExpectedPublicKey(targetNodeId); - if (!senderPublicKey) { - throw new nodesErrors.ErrorNodeConnectionPublicKeyNotFound(); - } - const verifiedSingly = - await claimsUtils.verifyIntermediaryClaimSignature( - constructedIntermediaryClaim, - senderPublicKey, - ); - if (!verifiedSingly) { - throw new claimsErrors.ErrorSinglySignedClaimVerificationFailed(); - } - // Verify the doubly signed claim with both our public key, and the sender's - const verifiedDoubly = - (await claimsUtils.verifyClaimSignature( - constructedDoublySignedClaim, - this.keyManager.getRootKeyPairPem().publicKey, - )) && - (await claimsUtils.verifyClaimSignature( - constructedDoublySignedClaim, - senderPublicKey, - )); - if (!verifiedDoubly) { - throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed(); - } - // 4. X <- responds with double signing the X signed claim <- Y - const doublySignedClaimResponse = - await claimsUtils.signIntermediaryClaim({ - claim: constructedIntermediaryClaim, - privateKey: this.keyManager.getRootKeyPairPem().privateKey, - signeeNodeId: nodesUtils.encodeNodeId( - this.keyManager.getNodeId(), - ), - }); - // Should never be reached, but just for type safety - if (!doublySignedClaimResponse.payload) { - throw new claimsErrors.ErrorClaimsUndefinedClaimPayload(); - } - const crossSignMessageResponse = claimsUtils.createCrossSignMessage( - { - doublySignedClaim: doublySignedClaimResponse, - }, + }, + tran, + ); + let doublySignedClaim: ClaimEncoded; + await this.nodeConnectionManager.withConnF( + targetNodeId, + async (connection) => { + const client = connection.getClient(); + const genClaims = client.nodesCrossSignClaim(); + try { + // 2. Set up the intermediary claim message (the singly signed claim) to send + const crossSignMessage = claimsUtils.createCrossSignMessage({ + singlySignedClaim: singlySignedClaim, + }); + await genClaims.write(crossSignMessage); // Get the generator here + // 3. We expect to receive our singly signed claim we sent to now be a + // doubly signed claim (signed by the other node), as well as a singly + // signed claim to be signed by us + const readStatus = await genClaims.read(); + // If nothing to read, end and destroy + if (readStatus.done) { + throw new claimsErrors.ErrorEmptyStream(); + } + const receivedMessage = readStatus.value; + const intermediaryClaimMessage = + receivedMessage.getSinglySignedClaim(); + const doublySignedClaimMessage = + receivedMessage.getDoublySignedClaim(); + // Ensure all of our expected messages are defined + if (!intermediaryClaimMessage) { + throw new claimsErrors.ErrorUndefinedSinglySignedClaim(); + } + const intermediaryClaimSignature = + intermediaryClaimMessage.getSignature(); + if (!intermediaryClaimSignature) { + throw new claimsErrors.ErrorUndefinedSignature(); + } + if (!doublySignedClaimMessage) { + throw new claimsErrors.ErrorUndefinedDoublySignedClaim(); + } + // Reconstruct the expected objects from the messages + const constructedIntermediaryClaim = + claimsUtils.reconstructClaimIntermediary(intermediaryClaimMessage); + const constructedDoublySignedClaim = + claimsUtils.reconstructClaimEncoded(doublySignedClaimMessage); + // Verify the singly signed claim with the sender's public key + const senderPublicKey = connection.getExpectedPublicKey(targetNodeId); + if (!senderPublicKey) { + throw new nodesErrors.ErrorNodeConnectionPublicKeyNotFound(); + } + const verifiedSingly = + await claimsUtils.verifyIntermediaryClaimSignature( + constructedIntermediaryClaim, + senderPublicKey, ); - await genClaims.write(crossSignMessageResponse); - - // Check the stream is closed (should be closed by other side) - const finalResponse = await genClaims.read(); - if (finalResponse.done != null) { - await genClaims.next(null); - } + if (!verifiedSingly) { + throw new claimsErrors.ErrorSinglySignedClaimVerificationFailed(); + } + // Verify the doubly signed claim with both our public key, and the sender's + const verifiedDoubly = + (await claimsUtils.verifyClaimSignature( + constructedDoublySignedClaim, + this.keyManager.getRootKeyPairPem().publicKey, + )) && + (await claimsUtils.verifyClaimSignature( + constructedDoublySignedClaim, + senderPublicKey, + )); + if (!verifiedDoubly) { + throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed(); + } + // 4. X <- responds with double signing the X signed claim <- Y + const doublySignedClaimResponse = + await claimsUtils.signIntermediaryClaim({ + claim: constructedIntermediaryClaim, + privateKey: this.keyManager.getRootKeyPairPem().privateKey, + signeeNodeId: nodesUtils.encodeNodeId( + this.keyManager.getNodeId(), + ), + }); + // Should never be reached, but just for type safety + if (!doublySignedClaimResponse.payload) { + throw new claimsErrors.ErrorClaimsUndefinedClaimPayload(); + } + const crossSignMessageResponse = claimsUtils.createCrossSignMessage({ + doublySignedClaim: doublySignedClaimResponse, + }); + await genClaims.write(crossSignMessageResponse); - doublySignedClaim = constructedDoublySignedClaim; - } catch (e) { - await genClaims.throw(e); - throw e; + // Check the stream is closed (should be closed by other side) + const finalResponse = await genClaims.read(); + if (finalResponse.done != null) { + await genClaims.next(null); } - await sigchain.addExistingClaim(doublySignedClaim); - }, - ); - }); + + doublySignedClaim = constructedDoublySignedClaim; + } catch (e) { + await genClaims.throw(e); + throw e; + } + await this.sigchain.addExistingClaim(doublySignedClaim, tran); + }, + ); } /** * Retrieves the node Address from the NodeGraph * @param nodeId node ID of the target node + * @param tran * @returns Node Address of the target node */ public async getNodeAddress( nodeId: NodeId, + tran?: DBTransaction, ): Promise { - return await this.nodeGraph.getNode(nodeId); + return await this.nodeGraph.getNode(nodeId, tran); } /** * Determines whether a node ID -> node address mapping exists in the NodeGraph * @param targetNodeId the node ID of the node to find + * @param tran * @returns true if the node exists in the table, false otherwise */ - public async knowsNode(targetNodeId: NodeId): Promise { - return await this.nodeGraph.knowsNode(targetNodeId); + public async knowsNode( + targetNodeId: NodeId, + tran?: DBTransaction, + ): Promise { + return await this.nodeGraph.knowsNode(targetNodeId, tran); } /** * Gets the specified bucket from the NodeGraph */ - public async getBucket(bucketIndex: number): Promise { - return await this.nodeGraph.getBucket(bucketIndex); + public async getBucket( + bucketIndex: number, + tran?: DBTransaction, + ): Promise { + return await this.nodeGraph.getBucket(bucketIndex, tran); } /** @@ -331,8 +345,9 @@ class NodeManager { public async setNode( nodeId: NodeId, nodeAddress: NodeAddress, + tran?: DBTransaction, ): Promise { - return await this.nodeGraph.setNode(nodeId, nodeAddress); + return await this.nodeGraph.setNode(nodeId, nodeAddress, tran); } /** @@ -341,30 +356,31 @@ class NodeManager { public async updateNode( nodeId: NodeId, nodeAddress?: NodeAddress, + tran?: DBTransaction, ): Promise { - return await this.nodeGraph.updateNode(nodeId, nodeAddress); + return await this.nodeGraph.updateNode(nodeId, nodeAddress, tran); } /** * Removes a node from the NodeGraph */ - public async unsetNode(nodeId: NodeId): Promise { - return await this.nodeGraph.unsetNode(nodeId); + public async unsetNode(nodeId: NodeId, tran?: DBTransaction): Promise { + return await this.nodeGraph.unsetNode(nodeId, tran); } /** * Gets all buckets from the NodeGraph */ - public async getAllBuckets(): Promise> { - return await this.nodeGraph.getAllBuckets(); + public async getAllBuckets(tran?: DBTransaction): Promise> { + return await this.nodeGraph.getAllBuckets(tran); } /** * To be called on key renewal. Re-orders all nodes in all buckets with respect * to the new node ID. */ - public async refreshBuckets(): Promise { - return await this.nodeGraph.refreshBuckets(); + public async refreshBuckets(tran?: DBTransaction): Promise { + return await this.nodeGraph.refreshBuckets(tran); } } diff --git a/src/nodes/errors.ts b/src/nodes/errors.ts index a7074ae41..1c491bde4 100644 --- a/src/nodes/errors.ts +++ b/src/nodes/errors.ts @@ -1,69 +1,69 @@ import { ErrorPolykey, sysexits } from '../errors'; -class ErrorNodes extends ErrorPolykey {} +class ErrorNodes extends ErrorPolykey {} -class ErrorNodeGraphRunning extends ErrorNodes { - description = 'NodeGraph is running'; +class ErrorNodeGraphRunning extends ErrorNodes { + static description = 'NodeGraph is running'; exitCode = sysexits.USAGE; } -class ErrorNodeGraphNotRunning extends ErrorNodes { - description = 'NodeGraph is not running'; +class ErrorNodeGraphNotRunning extends ErrorNodes { + static description = 'NodeGraph is not running'; exitCode = sysexits.USAGE; } -class ErrorNodeGraphDestroyed extends ErrorNodes { - description = 'NodeGraph is destroyed'; +class ErrorNodeGraphDestroyed extends ErrorNodes { + static description = 'NodeGraph is destroyed'; exitCode = sysexits.USAGE; } -class ErrorNodeGraphNodeIdNotFound extends ErrorNodes { - description = 'Could not find NodeId'; +class ErrorNodeGraphNodeIdNotFound extends ErrorNodes { + static description = 'Could not find NodeId'; exitCode = sysexits.NOUSER; } -class ErrorNodeGraphEmptyDatabase extends ErrorNodes { - description = 'NodeGraph database was empty'; +class ErrorNodeGraphEmptyDatabase extends ErrorNodes { + static description = 'NodeGraph database was empty'; exitCode = sysexits.USAGE; } -class ErrorNodeGraphOversizedBucket extends ErrorNodes { - description: 'Bucket invalidly contains more nodes than capacity'; +class ErrorNodeGraphOversizedBucket extends ErrorNodes { + static description: 'Bucket invalidly contains more nodes than capacity'; exitCode = sysexits.USAGE; } -class ErrorNodeGraphSameNodeId extends ErrorNodes { - description: 'NodeId must be different for valid bucket calculation'; +class ErrorNodeGraphSameNodeId extends ErrorNodes { + static description: 'NodeId must be different for valid bucket calculation'; exitCode = sysexits.USAGE; } -class ErrorNodeConnectionDestroyed extends ErrorNodes { - description = 'NodeConnection is destroyed'; +class ErrorNodeConnectionDestroyed extends ErrorNodes { + static description = 'NodeConnection is destroyed'; exitCode = sysexits.USAGE; } -class ErrorNodeConnectionTimeout extends ErrorNodes { - description: 'A node connection could not be established (timed out)'; +class ErrorNodeConnectionTimeout extends ErrorNodes { + static description: 'A node connection could not be established (timed out)'; exitCode = sysexits.UNAVAILABLE; } -class ErrorNodeConnectionInfoNotExist extends ErrorNodes { - description: 'NodeConnection info was not found'; +class ErrorNodeConnectionInfoNotExist extends ErrorNodes { + static description: 'NodeConnection info was not found'; exitCode = sysexits.UNAVAILABLE; } -class ErrorNodeConnectionPublicKeyNotFound extends ErrorNodes { - description: 'Public key was not found'; +class ErrorNodeConnectionPublicKeyNotFound extends ErrorNodes { + static description: 'Public key was not found'; exitCode = sysexits.UNAVAILABLE; } -class ErrorNodeConnectionManagerNotRunning extends ErrorNodes { - description = 'NodeConnectionManager is not running'; +class ErrorNodeConnectionManagerNotRunning extends ErrorNodes { + static description = 'NodeConnectionManager is not running'; exitCode = sysexits.USAGE; } -class ErrorNodeConnectionHostWildcard extends ErrorNodes { - description = 'An IP wildcard was provided for the target host'; +class ErrorNodeConnectionHostWildcard extends ErrorNodes { + static description = 'An IP wildcard was provided for the target host'; exitCode = sysexits.USAGE; } diff --git a/src/notifications/NotificationsManager.ts b/src/notifications/NotificationsManager.ts index 44974ae67..b2780000a 100644 --- a/src/notifications/NotificationsManager.ts +++ b/src/notifications/NotificationsManager.ts @@ -1,27 +1,28 @@ +import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { NotificationId, Notification, NotificationData, NotificationIdGenerator, } from './types'; -import type { ACL } from '../acl'; -import type { DB, DBLevel } from '@matrixai/db'; -import type { KeyManager } from '../keys'; -import type { NodeManager, NodeConnectionManager } from '../nodes'; +import type ACL from '../acl/ACL'; +import type KeyManager from '../keys/KeyManager'; +import type NodeManager from '../nodes/NodeManager'; +import type NodeConnectionManager from '../nodes/NodeConnectionManager'; import type { NodeId } from '../nodes/types'; import Logger from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; -import { Mutex } from 'async-mutex'; +import { Lock, LockBox } from '@matrixai/async-locks'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { utils as idUtils } from '@matrixai/id'; +import { withF } from '@matrixai/resources'; import * as notificationsUtils from './utils'; import * as notificationsErrors from './errors'; -import { createNotificationIdGenerator } from './utils'; import * as notificationsPB from '../proto/js/polykey/v1/notifications/notifications_pb'; -import { utils as nodesUtils } from '../nodes'; +import * as nodesUtils from '../nodes/utils'; const MESSAGE_COUNT_KEY = 'numMessages'; @@ -34,27 +35,6 @@ interface NotificationsManager extends CreateDestroyStartStop {} new notificationsErrors.ErrorNotificationsDestroyed(), ) class NotificationsManager { - protected logger: Logger; - protected acl: ACL; - protected db: DB; - protected keyManager: KeyManager; - protected nodeManager: NodeManager; - protected nodeConnectionManager: NodeConnectionManager; - - protected messageCap: number; - - protected notificationsDomain: string = this.constructor.name; - protected notificationsDbDomain: Array = [this.notificationsDomain]; - protected notificationsMessagesDbDomain: Array = [ - this.notificationsDomain, - 'messages', - ]; - protected notificationsDb: DBLevel; - protected notificationsMessagesDb: DBLevel; - protected lock: Mutex = new Mutex(); - - protected notificationIdGenerator: NotificationIdGenerator; - static async createNotificationsManager({ acl, db, @@ -90,6 +70,29 @@ class NotificationsManager { return notificationsManager; } + protected logger: Logger; + protected acl: ACL; + protected db: DB; + protected keyManager: KeyManager; + protected nodeManager: NodeManager; + protected nodeConnectionManager: NodeConnectionManager; + protected messageCap: number; + protected locks: LockBox = new LockBox(); + + /** + * Top level stores MESSAGE_COUNT_KEY -> number (of messages) + */ + protected notificationsDbPath: LevelPath = [this.constructor.name]; + /** + * Messages stores NotificationId -> string (message) + */ + protected notificationsMessagesDbPath: LevelPath = [ + this.constructor.name, + 'messages', + ]; + + protected notificationIdGenerator: NotificationIdGenerator; + constructor({ acl, db, @@ -116,38 +119,37 @@ class NotificationsManager { this.nodeManager = nodeManager; } - get locked(): boolean { - return this.lock.isLocked(); - } - public async start({ fresh = false, }: { fresh?: boolean } = {}): Promise { - this.logger.info(`Starting ${this.constructor.name}`); - // Sub-level stores MESSAGE_COUNT_KEY -> number (of messages) - const notificationsDb = await this.db.level(this.notificationsDomain); - // Sub-sub-level stores NotificationId -> string (message) - const notificationsMessagesDb = await this.db.level( - this.notificationsMessagesDbDomain[1], - notificationsDb, - ); - if (fresh) { - await notificationsDb.clear(); - } - this.notificationsDb = notificationsDb; - this.notificationsMessagesDb = notificationsMessagesDb; + await withF( + [ + this.db.transaction(), + this.locks.lock([ + [...this.notificationsDbPath, MESSAGE_COUNT_KEY], + Lock, + ]), + ], + async ([tran]) => { + this.logger.info(`Starting ${this.constructor.name}`); + if (fresh) { + await tran.clear(this.notificationsDbPath); + } - // Getting latest ID and creating ID generator - let latestId: NotificationId | undefined; - const keyStream = this.notificationsMessagesDb.createKeyStream({ - limit: 1, - reverse: true, - }); - for await (const o of keyStream) { - latestId = IdInternal.fromBuffer(o as Buffer); - } - this.notificationIdGenerator = createNotificationIdGenerator(latestId); - this.logger.info(`Started ${this.constructor.name}`); + // Getting latest ID and creating ID generator + let latestId: NotificationId | undefined; + const keyIterator = tran.iterator( + { limit: 1, reverse: true }, + this.notificationsMessagesDbPath, + ); + for await (const [key] of keyIterator) { + latestId = IdInternal.fromBuffer(key); + } + this.notificationIdGenerator = + notificationsUtils.createNotificationIdGenerator(latestId); + this.logger.info(`Started ${this.constructor.name}`); + }, + ); } public async stop() { @@ -157,37 +159,24 @@ class NotificationsManager { public async destroy() { this.logger.info(`Destroying ${this.constructor.name}`); - const notificationsDb = await this.db.level(this.notificationsDomain); - await notificationsDb.clear(); + await this.db.withTransactionF(async (tran) => { + await tran.clear(this.notificationsDbPath); + }); this.logger.info(`Destroyed ${this.constructor.name}`); } - /** - * Run several operations within the same lock - * This does not ensure atomicity of the underlying database - * Database atomicity still depends on the underlying operation - */ - public async transaction( - f: (notificationsManager: NotificationsManager) => Promise, + @ready(new notificationsErrors.ErrorNotificationsNotRunning()) + public async withTransactionF( + ...params: [...keys: Array, f: (tran: DBTransaction) => Promise] ): Promise { - const release = await this.lock.acquire(); - try { - return await f(this); - } finally { - release(); - } - } - - /** - * Transaction wrapper that will not lock if the operation was executed - * within a transaction context - */ - public async _transaction(f: () => Promise): Promise { - if (this.lock.isLocked()) { - return await f(); - } else { - return await this.transaction(f); - } + const f = params.pop() as (tran: DBTransaction) => Promise; + const lockRequests = (params as Array).map<[KeyPath, typeof Lock]>( + (key) => [key, Lock], + ); + return withF( + [this.db.transaction(), this.locks.lock(...lockRequests)], + ([tran]) => f(tran), + ); } /** @@ -195,7 +184,10 @@ class NotificationsManager { * The `data` parameter must match one of the NotificationData types outlined in ./types */ @ready(new notificationsErrors.ErrorNotificationsNotRunning()) - public async sendNotification(nodeId: NodeId, data: NotificationData) { + public async sendNotification( + nodeId: NodeId, + data: NotificationData, + ): Promise { const notification = { data: data, senderId: nodesUtils.encodeNodeId(this.keyManager.getNodeId()), @@ -217,46 +209,45 @@ class NotificationsManager { * Receive a notification */ @ready(new notificationsErrors.ErrorNotificationsNotRunning()) - public async receiveNotification(notification: Notification) { - await this._transaction(async () => { - const nodePerms = await this.acl.getNodePerm( - nodesUtils.decodeNodeId(notification.senderId)!, + public async receiveNotification( + notification: Notification, + tran?: DBTransaction, + ): Promise { + const messageCountPath = [...this.notificationsDbPath, MESSAGE_COUNT_KEY]; + if (tran == null) { + return this.withTransactionF(messageCountPath, async (tran) => + this.receiveNotification(notification, tran), ); - if (nodePerms === undefined) { - throw new notificationsErrors.ErrorNotificationsPermissionsNotFound(); + } + const nodePerms = await this.acl.getNodePerm( + nodesUtils.decodeNodeId(notification.senderId)!, + ); + if (nodePerms === undefined) { + throw new notificationsErrors.ErrorNotificationsPermissionsNotFound(); + } + // Only keep the message if the sending node has the correct permissions + if (Object.keys(nodePerms.gestalt).includes('notify')) { + // If the number stored in notificationsDb >= 10000 + let numMessages = await tran.get(messageCountPath); + if (numMessages === undefined) { + numMessages = 0; + await tran.put(messageCountPath, 0); } - // Only keep the message if the sending node has the correct permissions - if (Object.keys(nodePerms.gestalt).includes('notify')) { - // If the number stored in notificationsDb >= 10000 - let numMessages = await this.db.get( - this.notificationsDbDomain, - MESSAGE_COUNT_KEY, - ); - if (numMessages === undefined) { - numMessages = 0; - await this.db.put(this.notificationsDbDomain, MESSAGE_COUNT_KEY, 0); - } - if (numMessages >= this.messageCap) { - // Remove the oldest notification from notificationsMessagesDb - const oldestId = await this.getOldestNotificationId(); - await this.removeNotification(oldestId!); - } - // Store the new notification in notificationsMessagesDb - const notificationId = this.notificationIdGenerator(); - await this.db.put( - this.notificationsMessagesDbDomain, - idUtils.toBuffer(notificationId), - notification, - ); - // Number of messages += 1 - const newNumMessages = numMessages + 1; - await this.db.put( - this.notificationsDbDomain, - MESSAGE_COUNT_KEY, - newNumMessages, - ); + if (numMessages >= this.messageCap) { + // Remove the oldest notification from notificationsMessagesDb + const oldestId = await this.getOldestNotificationId(tran); + await this.removeNotification(oldestId!, tran); } - }); + // Store the new notification in notificationsMessagesDb + const notificationId = this.notificationIdGenerator(); + await tran.put( + [...this.notificationsMessagesDbPath, idUtils.toBuffer(notificationId)], + notification, + ); + // Number of messages += 1 + const newNumMessages = numMessages + 1; + await tran.put(messageCountPath, newNumMessages); + } } /** @@ -267,16 +258,23 @@ class NotificationsManager { unread = false, number = 'all', order = 'newest', + tran, }: { unread?: boolean; number?: number | 'all'; order?: 'newest' | 'oldest'; + tran?: DBTransaction; } = {}): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.readNotifications({ unread, number, order, tran }), + ); + } let notificationIds: Array; - if (unread === true) { - notificationIds = await this.getNotificationIds('unread'); + if (unread) { + notificationIds = await this.getNotificationIds('unread', tran); } else { - notificationIds = await this.getNotificationIds('all'); + notificationIds = await this.getNotificationIds('all', tran); } if (order === 'newest') { @@ -290,7 +288,7 @@ class NotificationsManager { const notifications: Array = []; for (const id of notificationIds) { - const notification = await this.readNotificationById(id); + const notification = await this.readNotificationById(id, tran); notifications.push(notification!); } @@ -304,8 +302,14 @@ class NotificationsManager { @ready(new notificationsErrors.ErrorNotificationsNotRunning()) public async findGestaltInvite( fromNode: NodeId, + tran?: DBTransaction, ): Promise { - const notifications = await this.getNotifications('all'); + if (tran == null) { + return this.withTransactionF(async (tran) => + this.findGestaltInvite(fromNode, tran), + ); + } + const notifications = await this.getNotifications('all', tran); for (const notification of notifications) { if ( notification.data.type === 'GestaltInvite' && @@ -320,119 +324,112 @@ class NotificationsManager { * Removes all notifications */ @ready(new notificationsErrors.ErrorNotificationsNotRunning()) - public async clearNotifications() { - await this._transaction(async () => { - const notificationIds = await this.getNotificationIds('all'); - const numMessages = await this.db.get( - this.notificationsDbDomain, - MESSAGE_COUNT_KEY, + public async clearNotifications(tran?: DBTransaction): Promise { + const messageCountPath = [...this.notificationsDbPath, MESSAGE_COUNT_KEY]; + if (tran == null) { + return this.withTransactionF(messageCountPath, async (tran) => + this.clearNotifications(tran), ); - if (numMessages !== undefined) { - for (const id of notificationIds) { - await this.removeNotification(id); - } + } + const notificationIds = await this.getNotificationIds('all', tran); + const numMessages = await tran.get(messageCountPath); + if (numMessages !== undefined) { + for (const id of notificationIds) { + await this.removeNotification(id, tran); } - }); + } } - private async readNotificationById( + protected async readNotificationById( notificationId: NotificationId, + tran: DBTransaction, ): Promise { - return await this._transaction(async () => { - const notification = await this.db.get( - this.notificationsMessagesDbDomain, - idUtils.toBuffer(notificationId), - ); - if (notification === undefined) { - return undefined; - } - notification.isRead = true; - await this.db.put( - this.notificationsMessagesDbDomain, - idUtils.toBuffer(notificationId), - notification, - ); - return notification; - }); + const notification = await tran.get([ + ...this.notificationsMessagesDbPath, + idUtils.toBuffer(notificationId), + ]); + if (notification === undefined) { + return undefined; + } + notification.isRead = true; + await tran.put( + [...this.notificationsMessagesDbPath, idUtils.toBuffer(notificationId)], + notification, + ); + return notification; } - private async getNotificationIds( + protected async getNotificationIds( type: 'unread' | 'all', + tran: DBTransaction, ): Promise> { - return await this._transaction(async () => { - const notificationIds: Array = []; - for await (const o of this.notificationsMessagesDb.createReadStream()) { - const notificationId = IdInternal.fromBuffer( - (o as any).key, - ); - const data = (o as any).value as Buffer; - const notification = await this.db.deserializeDecrypt( - data, - false, - ); - if (type === 'all') { + const notificationIds: Array = []; + const messageIterator = tran.iterator({}, this.notificationsMessagesDbPath); + for await (const [key, value] of messageIterator) { + const notificationId = IdInternal.fromBuffer(key); + const notification = JSON.parse(value.toString()) as Notification; + if (type === 'all') { + notificationIds.push(notificationId); + } else if (type === 'unread') { + if (!notification.isRead) { notificationIds.push(notificationId); - } else if (type === 'unread') { - if (notification.isRead === false) { - notificationIds.push(notificationId); - } } } - return notificationIds; - }); + } + return notificationIds; } - private async getNotifications( + protected async getNotifications( type: 'unread' | 'all', + tran: DBTransaction, ): Promise> { - return await this._transaction(async () => { - const notifications: Array = []; - for await (const v of this.notificationsMessagesDb.createValueStream()) { - const data = v as Buffer; - const notification = await this.db.deserializeDecrypt( - data, - false, - ); - if (type === 'all') { + const notifications: Array = []; + for await (const [, value] of tran.iterator( + {}, + this.notificationsMessagesDbPath, + )) { + const notification = JSON.parse(value.toString()) as Notification; + if (type === 'all') { + notifications.push(notification); + } else if (type === 'unread') { + if (!notification.isRead) { notifications.push(notification); - } else if (type === 'unread') { - if (notification.isRead === false) { - notifications.push(notification); - } } } - return notifications; - }); + } + return notifications; } - private async getOldestNotificationId(): Promise { - const notificationIds = await this.getNotificationIds('all'); + protected async getOldestNotificationId( + tran: DBTransaction, + ): Promise { + const notificationIds = await this.getNotificationIds('all', tran); if (notificationIds.length === 0) { return undefined; } return notificationIds[0]; } - private async removeNotification(messageId: NotificationId) { - await this._transaction(async () => { - const numMessages = await this.db.get( - this.notificationsDbDomain, - MESSAGE_COUNT_KEY, - ); - if (numMessages === undefined) { - throw new notificationsErrors.ErrorNotificationsDb(); - } + protected async removeNotification( + messageId: NotificationId, + tran: DBTransaction, + ): Promise { + const numMessages = await tran.get([ + ...this.notificationsDbPath, + MESSAGE_COUNT_KEY, + ]); + if (numMessages === undefined) { + throw new notificationsErrors.ErrorNotificationsDb(); + } - await this.db.del( - this.notificationsMessagesDbDomain, - idUtils.toBuffer(messageId), - ); - await this.db.put( - this.notificationsDbDomain, - MESSAGE_COUNT_KEY, - numMessages - 1, - ); - }); + await tran.del([ + ...this.notificationsMessagesDbPath, + idUtils.toBuffer(messageId), + ]); + await tran.put( + [...this.notificationsDbPath, MESSAGE_COUNT_KEY], + numMessages - 1, + ); } } diff --git a/src/notifications/errors.ts b/src/notifications/errors.ts index 5d6f68493..028862e50 100644 --- a/src/notifications/errors.ts +++ b/src/notifications/errors.ts @@ -1,39 +1,69 @@ -import { ErrorPolykey } from '../errors'; +import { ErrorPolykey, sysexits } from '../errors'; -class ErrorNotifications extends ErrorPolykey {} +class ErrorNotifications extends ErrorPolykey {} -class ErrorNotificationsUnknownNode extends ErrorNotifications {} +class ErrorNotificationsRunning extends ErrorNotifications { + static description = 'NotiticationsManager is running'; + exitCode = sysexits.USAGE; +} -class ErrorNotificationsRunning extends ErrorNotifications {} +class ErrorNotificationsNotRunning extends ErrorNotifications { + static description = 'NotiticationsManager is not running'; + exitCode = sysexits.USAGE; +} -class ErrorNotificationsNotRunning extends ErrorNotifications {} +class ErrorNotificationsDestroyed extends ErrorNotifications { + static description = 'NotiticationsManager is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorNotificationsDestroyed extends ErrorNotifications {} +class ErrorNotificationsPermissionsNotFound extends ErrorNotifications { + static description = 'Could not find permissions for NodeId'; + exitCode = sysexits.NOUSER; +} -class ErrorNotificationsPermissionsNotFound extends ErrorNotifications {} +class ErrorNotificationsDb extends ErrorNotifications { + static description = 'Database consistency error'; + exitCode = sysexits.IOERR; +} -class ErrorNotificationsDb extends ErrorNotifications {} - -class ErrorNotificationsParse extends ErrorNotifications {} +class ErrorNotificationsParse extends ErrorNotifications { + static description = 'Unable to verify notification'; + exitCode = sysexits.IOERR; +} /** * Exceptions raised when validating a Notification against a JSON schema */ -class ErrorSchemaValidate extends ErrorNotifications {} +class ErrorSchemaValidate extends ErrorNotifications {} -class ErrorNotificationsInvalidType extends ErrorSchemaValidate {} +class ErrorNotificationsInvalidType extends ErrorSchemaValidate { + static description = 'Invalid notification type'; + exitCode = sysexits.USAGE; +} -class ErrorNotificationsGeneralInvalid extends ErrorSchemaValidate {} +class ErrorNotificationsGeneralInvalid extends ErrorSchemaValidate { + static description = 'Invalid notification data'; + exitCode = sysexits.USAGE; +} -class ErrorNotificationsGestaltInviteInvalid extends ErrorSchemaValidate {} +class ErrorNotificationsGestaltInviteInvalid extends ErrorSchemaValidate { + static description = 'Invalid notification data'; + exitCode = sysexits.USAGE; +} -class ErrorNotificationsVaultShareInvalid extends ErrorSchemaValidate {} +class ErrorNotificationsVaultShareInvalid extends ErrorSchemaValidate { + static description = 'Invalid notification data'; + exitCode = sysexits.USAGE; +} -class ErrorNotificationsValidationFailed extends ErrorSchemaValidate {} +class ErrorNotificationsValidationFailed extends ErrorSchemaValidate { + static description = 'Notification does not match schema'; + exitCode = sysexits.USAGE; +} export { ErrorNotifications, - ErrorNotificationsUnknownNode, ErrorNotificationsRunning, ErrorNotificationsNotRunning, ErrorNotificationsDestroyed, diff --git a/src/notifications/utils.ts b/src/notifications/utils.ts index 08532f524..a31b0ad59 100644 --- a/src/notifications/utils.ts +++ b/src/notifications/utils.ts @@ -78,7 +78,9 @@ async function verifyAndDecodeNotif(notifJWT: string): Promise { throw err; } else { // Error came from jose - throw new notificationsErrors.ErrorNotificationsParse(); + throw new notificationsErrors.ErrorNotificationsParse(err.message, { + cause: err, + }); } } } diff --git a/src/schema/Schema.ts b/src/schema/Schema.ts index 546d81956..b7c66be4c 100644 --- a/src/schema/Schema.ts +++ b/src/schema/Schema.ts @@ -1,9 +1,9 @@ import type { StateVersion } from './types'; import type { FileSystem } from '../types'; - import path from 'path'; import Logger from '@matrixai/logger'; import { CreateDestroyStartStop } from '@matrixai/async-init/dist/CreateDestroyStartStop'; +import { RWLockWriter } from '@matrixai/async-locks'; import * as schemaErrors from './errors'; import * as utils from '../utils'; import config from '../config'; @@ -17,14 +17,12 @@ class Schema { public static async createSchema({ statePath, stateVersion = config.stateVersion as StateVersion, - lock = new utils.RWLock(), fs = require('fs'), logger = new Logger(this.name), fresh = false, }: { statePath: string; stateVersion?: StateVersion; - lock?: utils.RWLock; fs?: FileSystem; logger?: Logger; fresh?: boolean; @@ -33,7 +31,6 @@ class Schema { const schema = new Schema({ statePath, stateVersion, - lock, fs, logger, }); @@ -45,20 +42,18 @@ class Schema { public readonly statePath: string; public readonly stateVersionPath: string; public readonly stateVersion: StateVersion; - protected lock: utils.RWLock; + protected lock: RWLockWriter = new RWLockWriter(); protected fs: FileSystem; protected logger: Logger; public constructor({ statePath, stateVersion = config.stateVersion as StateVersion, - lock = new utils.RWLock(), fs = require('fs'), logger, }: { statePath: string; stateVersion?: StateVersion; - lock?: utils.RWLock; fs?: FileSystem; logger?: Logger; }) { @@ -69,7 +64,6 @@ class Schema { config.defaults.stateVersionBase, ); this.stateVersion = stateVersion; - this.lock = lock; this.fs = fs; } @@ -88,10 +82,13 @@ class Schema { }); } catch (e) { throw new schemaErrors.ErrorSchemaStateDelete(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } @@ -99,10 +96,13 @@ class Schema { await utils.mkdirExists(this.fs, this.statePath); } catch (e) { throw new schemaErrors.ErrorSchemaStateCreate(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } const stateVersion = await this.readVersion(); @@ -132,17 +132,20 @@ class Schema { }); } catch (e) { throw new schemaErrors.ErrorSchemaStateDelete(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } this.logger.info(`Destroyed ${this.constructor.name}`); } public async readVersion(): Promise { - return await this.lock.withRead(async () => { + return await this.lock.withReadF(async () => { let stateVersionData: string; try { stateVersionData = await this.fs.promises.readFile( @@ -154,10 +157,13 @@ class Schema { return; } throw new schemaErrors.ErrorSchemaVersionRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } const stateVersion = parseInt(stateVersionData.trim()); @@ -169,7 +175,7 @@ class Schema { } protected async writeVersion(stateVersion: StateVersion): Promise { - return await this.lock.withWrite(async () => { + return await this.lock.withWriteF(async () => { try { await this.fs.promises.writeFile( this.stateVersionPath, @@ -178,10 +184,13 @@ class Schema { ); } catch (e) { throw new schemaErrors.ErrorSchemaVersionWrite(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } }); @@ -191,7 +200,7 @@ class Schema { * This is only called when the version is older. */ protected async upgradeVersion(_stateVersion: StateVersion): Promise { - return await this.lock.withWrite(async () => { + return await this.lock.withWriteF(async () => { // TODO: to be implemented throw new schemaErrors.ErrorSchemaVersionTooOld(); }); diff --git a/src/schema/errors.ts b/src/schema/errors.ts index ee5b8b01b..973961386 100644 --- a/src/schema/errors.ts +++ b/src/schema/errors.ts @@ -1,30 +1,60 @@ -import { ErrorPolykey } from '../errors'; +import { ErrorPolykey, sysexits } from '../errors'; -class ErrorSchema extends ErrorPolykey {} +class ErrorSchema extends ErrorPolykey {} -class ErrorSchemaRunning extends ErrorSchema {} +class ErrorSchemaRunning extends ErrorSchema { + static description = 'Schema is running'; + exitCode = sysexits.USAGE; +} -class ErrorSchemaNotRunning extends ErrorSchema {} +class ErrorSchemaNotRunning extends ErrorSchema { + static description = 'Schema is not running'; + exitCode = sysexits.USAGE; +} -class ErrorSchemaDestroyed extends ErrorSchema {} +class ErrorSchemaDestroyed extends ErrorSchema { + static description = 'Schema is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorSchemaStateCreate extends ErrorSchema {} +class ErrorSchemaStateCreate extends ErrorSchema { + static description = 'Unable to create schema state'; + exitCode = sysexits.IOERR; +} -class ErrorSchemaStateDelete extends ErrorSchema {} +class ErrorSchemaStateDelete extends ErrorSchema { + static description = 'Unable to delete schema state'; + exitCode = sysexits.IOERR; +} -class ErrorSchemaVersionRead extends ErrorSchema {} +class ErrorSchemaVersionRead extends ErrorSchema { + static description = 'Unable to read schema version'; + exitCode = sysexits.IOERR; +} -class ErrorSchemaVersionParse extends ErrorSchema {} +class ErrorSchemaVersionParse extends ErrorSchema { + static description = 'Invalid schema version'; + exitCode = sysexits.IOERR; +} -class ErrorSchemaVersionWrite extends ErrorSchema {} +class ErrorSchemaVersionWrite extends ErrorSchema { + static description = 'Unable to write schema version'; + exitCode = sysexits.IOERR; +} -class ErrorSchemaVersionTooNew extends ErrorSchema {} +class ErrorSchemaVersionTooNew extends ErrorSchema { + static description = 'Invalid state version'; + exitCode = sysexits.USAGE; +} -class ErrorSchemaVersionTooOld extends ErrorSchema {} +class ErrorSchemaVersionTooOld extends ErrorSchema { + static description = 'Unable to upgrade schema version'; + exitCode = sysexits.USAGE; +} -class ErrorSchemaMigrationFail extends ErrorSchema {} +class ErrorSchemaMigrationFail extends ErrorSchema {} -class ErrorSchemaMigrationMissing extends ErrorSchema {} +class ErrorSchemaMigrationMissing extends ErrorSchema {} export { ErrorSchema, diff --git a/src/sessions/SessionManager.ts b/src/sessions/SessionManager.ts index 6ee4bbbc9..f7e618a0b 100644 --- a/src/sessions/SessionManager.ts +++ b/src/sessions/SessionManager.ts @@ -1,17 +1,16 @@ -import type { DB, DBLevel } from '@matrixai/db'; +import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; import type { SessionToken } from './types'; -import type { KeyManager } from '../keys'; - +import type KeyManager from '../keys/KeyManager'; import Logger from '@matrixai/logger'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; -import { Mutex } from 'async-mutex'; +import { withF } from '@matrixai/resources'; import * as sessionsUtils from './utils'; import * as sessionsErrors from './errors'; import * as keysUtils from '../keys/utils'; -import { utils as nodesUtils } from '../nodes'; +import * as nodesUtils from '../nodes/utils'; interface SessionManager extends CreateDestroyStartStop {} @CreateDestroyStartStop( @@ -53,10 +52,7 @@ class SessionManager { protected logger: Logger; protected db: DB; protected keyManager: KeyManager; - protected sessionsDbDomain: string = this.constructor.name; - protected sessionsDb: DBLevel; - protected lock: Mutex = new Mutex(); - protected key: Uint8Array; + protected sessionsDbPath: LevelPath = [this.constructor.name]; public constructor({ db, @@ -78,23 +74,16 @@ class SessionManager { this.keyBits = keyBits; } - get locked(): boolean { - return this.lock.isLocked(); - } - public async start({ fresh = false, }: { fresh?: boolean; } = {}): Promise { this.logger.info(`Starting ${this.constructor.name}`); - const sessionsDb = await this.db.level(this.sessionsDbDomain); if (fresh) { - await sessionsDb.clear(); + await this.db.clear(this.sessionsDbPath); } - const key = await this.setupKey(this.keyBits); - this.sessionsDb = sessionsDb; - this.key = key; + await this.setupKey(this.keyBits); this.logger.info(`Started ${this.constructor.name}`); } @@ -105,44 +94,24 @@ class SessionManager { public async destroy() { this.logger.info(`Destroying ${this.constructor.name}`); - const sessionsDb = await this.db.level(this.sessionsDbDomain); - await sessionsDb.clear(); + await this.db.clear(this.sessionsDbPath); this.logger.info(`Destroyed ${this.constructor.name}`); } - /** - * Run several operations within the same lock - * This does not ensure atomicity of the underlying database - * Database atomicity still depends on the underlying operation - */ - public async transaction(f: (that: this) => Promise): Promise { - const release = await this.lock.acquire(); - try { - return await f(this); - } finally { - release(); - } - } - - /** - * Transaction wrapper that will not lock if the operation was executed - * within a transaction context - */ - protected async _transaction(f: () => Promise): Promise { - if (this.locked) { - return await f(); - } else { - return await this.transaction(f); - } + @ready(new sessionsErrors.ErrorSessionManagerNotRunning()) + public async withTransactionF( + f: (tran: DBTransaction) => Promise, + ): Promise { + return withF([this.db.transaction()], ([tran]) => f(tran)); } @ready(new sessionsErrors.ErrorSessionManagerNotRunning()) - public async resetKey(): Promise { - await this._transaction(async () => { - const key = await this.generateKey(this.keyBits); - await this.db.put([this.sessionsDbDomain], 'key', key, true); - this.key = key; - }); + public async resetKey(tran?: DBTransaction): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => this.resetKey(tran)); + } + const key = await this.generateKey(this.keyBits); + await tran.put([...this.sessionsDbPath, 'key'], key, true); } /** @@ -153,35 +122,49 @@ class SessionManager { @ready(new sessionsErrors.ErrorSessionManagerNotRunning()) public async createToken( expiry: number | undefined = this.expiry, + tran?: DBTransaction, ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.createToken(expiry, tran), + ); + } const payload = { iss: nodesUtils.encodeNodeId(this.keyManager.getNodeId()), sub: nodesUtils.encodeNodeId(this.keyManager.getNodeId()), }; - const token = await sessionsUtils.createSessionToken( - payload, - this.key, - expiry, - ); + const key = await tran.get([...this.sessionsDbPath, 'key'], true); + const token = await sessionsUtils.createSessionToken(payload, key!, expiry); return token; } @ready(new sessionsErrors.ErrorSessionManagerNotRunning()) - public async verifyToken(token: SessionToken): Promise { - const result = await sessionsUtils.verifySessionToken(token, this.key); + public async verifyToken( + token: SessionToken, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.verifyToken(token, tran), + ); + } + const key = await tran.get([...this.sessionsDbPath, 'key'], true); + const result = await sessionsUtils.verifySessionToken(token, key!); return result !== undefined; } protected async setupKey(bits: 128 | 192 | 256): Promise { - let key: Buffer | undefined; - key = await this.db.get([this.sessionsDbDomain], 'key', true); - if (key != null) { + return await withF([this.db.transaction()], async ([tran]) => { + let key: Buffer | undefined; + key = await tran.get([...this.sessionsDbPath, 'key'], true); + if (key != null) { + return key; + } + this.logger.info('Generating sessions key'); + key = await this.generateKey(bits); + await tran.put([...this.sessionsDbPath, 'key'], key, true); return key; - } - this.logger.info('Generating sessions key'); - key = await this.generateKey(bits); - await this.db.put([this.sessionsDbDomain], 'key', key, true); - return key; + }); } protected async generateKey(bits: 128 | 192 | 256): Promise { diff --git a/src/sessions/errors.ts b/src/sessions/errors.ts index 837020898..588ff9036 100644 --- a/src/sessions/errors.ts +++ b/src/sessions/errors.ts @@ -1,18 +1,36 @@ -import { ErrorPolykey } from '../errors'; - -class ErrorSessions extends ErrorPolykey {} - -class ErrorSessionRunning extends ErrorSessions {} - -class ErrorSessionNotRunning extends ErrorSessions {} - -class ErrorSessionDestroyed extends ErrorSessions {} - -class ErrorSessionManagerRunning extends ErrorSessions {} - -class ErrorSessionManagerNotRunning extends ErrorSessions {} - -class ErrorSessionManagerDestroyed extends ErrorSessions {} +import { ErrorPolykey, sysexits } from '../errors'; + +class ErrorSessions extends ErrorPolykey {} + +class ErrorSessionRunning extends ErrorSessions { + static description = 'Session is running'; + exitCode = sysexits.USAGE; +} + +class ErrorSessionNotRunning extends ErrorSessions { + static description = 'Session is not running'; + exitCode = sysexits.USAGE; +} + +class ErrorSessionDestroyed extends ErrorSessions { + static description = 'Session is destroyed'; + exitCode = sysexits.USAGE; +} + +class ErrorSessionManagerRunning extends ErrorSessions { + static description = 'SessionManager is running'; + exitCode = sysexits.USAGE; +} + +class ErrorSessionManagerNotRunning extends ErrorSessions { + static description = 'SessionManager is not running'; + exitCode = sysexits.USAGE; +} + +class ErrorSessionManagerDestroyed extends ErrorSessions { + static description = 'SessionManager is destroyed'; + exitCode = sysexits.USAGE; +} export { ErrorSessions, diff --git a/src/sigchain/Sigchain.ts b/src/sigchain/Sigchain.ts index 5d5744bf4..25614e490 100644 --- a/src/sigchain/Sigchain.ts +++ b/src/sigchain/Sigchain.ts @@ -1,4 +1,4 @@ -import type { DB, DBLevel, DBOp } from '@matrixai/db'; +import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { ChainDataEncoded } from './types'; import type { ClaimData, @@ -8,15 +8,17 @@ import type { ClaimIntermediary, ClaimType, } from '../claims/types'; -import type { KeyManager } from '../keys'; +import type KeyManager from '../keys/KeyManager'; import type { NodeIdEncoded } from '../nodes/types'; import Logger from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; -import { Mutex } from 'async-mutex'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; +import { utils as dbUtils } from '@matrixai/db'; +import { Lock, LockBox } from '@matrixai/async-locks'; +import { withF } from '@matrixai/resources'; import * as sigchainErrors from './errors'; import * as claimsUtils from '../claims/utils'; @@ -26,30 +28,23 @@ interface Sigchain extends CreateDestroyStartStop {} new sigchainErrors.ErrorSigchainDestroyed(), ) class Sigchain { - public readonly sigchainPath: string; - public readonly sigchainDbPath: string; protected readonly sequenceNumberKey: string = 'prevSequenceNumber'; protected logger: Logger; protected keyManager: KeyManager; protected db: DB; - protected sigchainDbDomain: string = this.constructor.name; - protected sigchainClaimsDbDomain: Array = [ - this.sigchainDbDomain, - 'claims', - ]; - protected sigchainMetadataDbDomain: Array = [ - this.sigchainDbDomain, - 'metadata', - ]; - protected sigchainDb: DBLevel; + protected locks: LockBox = new LockBox(); + // Top-level database for the sigchain domain + protected sigchainDbPath: LevelPath = [this.constructor.name]; // ClaimId (the lexicographic integer of the sequence number) // -> ClaimEncoded (a JWS in General JSON Serialization) - protected sigchainClaimsDb: DBLevel; + protected sigchainClaimsDbPath: LevelPath = [this.constructor.name, 'claims']; // Sub-level database for numerical metadata to be persisted // e.g. "sequenceNumber" -> current sequence number - protected sigchainMetadataDb: DBLevel; - protected lock: Mutex = new Mutex(); + protected sigchainMetadataDbPath: LevelPath = [ + this.constructor.name, + 'metadata', + ]; protected generateClaimId: ClaimIdGenerator; @@ -85,61 +80,37 @@ class Sigchain { this.keyManager = keyManager; } - get locked(): boolean { - return this.lock.isLocked(); - } - public async start({ fresh = false, }: { fresh?: boolean; } = {}): Promise { this.logger.info(`Starting ${this.constructor.name}`); - // Top-level database for the sigchain domain - const sigchainDb = await this.db.level(this.sigchainDbDomain); - // ClaimId (the lexicographic integer of the sequence number) - // -> ClaimEncoded (a JWS in General JSON Serialization) - const sigchainClaimsDb = await this.db.level( - this.sigchainClaimsDbDomain[1], - sigchainDb, - ); - // Sub-level database for numerical metadata to be persisted - // e.g. "sequenceNumber" -> current sequence number - const sigchainMetadataDb = await this.db.level( - this.sigchainMetadataDbDomain[1], - sigchainDb, - ); if (fresh) { - await sigchainDb.clear(); + await this.db.clear(this.sigchainDbPath); } - this.sigchainDb = sigchainDb; - this.sigchainClaimsDb = sigchainClaimsDb; - this.sigchainMetadataDb = sigchainMetadataDb; - // Initialise the sequence number (if not already done). // First claim in the sigchain has a sequence number of 1. // Therefore, with no claims in the sigchain, the previous sequence number // is set to 0. - await this._transaction(async () => { - const sequenceNumber = await this.db.get( - this.sigchainMetadataDbDomain, + await withF([this.db.transaction()], async ([tran]) => { + const sequenceNumber = await tran.get([ + ...this.sigchainMetadataDbPath, this.sequenceNumberKey, - ); + ]); if (sequenceNumber == null) { - await this.db.put( - this.sigchainMetadataDbDomain, - this.sequenceNumberKey, + await tran.put( + [...this.sigchainMetadataDbPath, this.sequenceNumberKey], 0, ); } + // Creating the ID generator + const latestId = await this.getLatestClaimId(tran); + this.generateClaimId = claimsUtils.createClaimIdGenerator( + this.keyManager.getNodeId(), + latestId, + ); }); - - // Creating the ID generator - const latestId = await this.getLatestClaimId(); - this.generateClaimId = claimsUtils.createClaimIdGenerator( - this.keyManager.getNodeId(), - latestId, - ); this.logger.info(`Started ${this.constructor.name}`); } @@ -150,35 +121,22 @@ class Sigchain { public async destroy() { this.logger.info(`Destroying ${this.constructor.name}`); - const sigchainDb = await this.db.level(this.sigchainDbDomain); - await sigchainDb.clear(); + await this.db.clear(this.sigchainDbPath); this.logger.info(`Destroyed ${this.constructor.name}`); } - /** - * Run several operations within the same lock - * This does not ensure atomicity of the underlying database - * Database atomicity still depends on the underlying operation - */ - public async transaction(f: (that: this) => Promise): Promise { - const release = await this.lock.acquire(); - try { - return await f(this); - } finally { - release(); - } - } - - /** - * Transaction wrapper that will not lock if the operation was executed - * within a transaction context - */ - protected async _transaction(f: () => Promise): Promise { - if (this.lock.isLocked()) { - return await f(); - } else { - return await this.transaction(f); - } + @ready(new sigchainErrors.ErrorSigchainNotRunning()) + public async withTransactionF( + ...params: [...keys: Array, f: (tran: DBTransaction) => Promise] + ): Promise { + const f = params.pop() as (tran: DBTransaction) => Promise; + const lockRequests = (params as Array).map<[KeyPath, typeof Lock]>( + (key) => [key, Lock], + ); + return withF( + [this.db.transaction(), this.locks.lock(...lockRequests)], + ([tran]) => f(tran), + ); } /** @@ -220,36 +178,32 @@ class Sigchain { @ready(new sigchainErrors.ErrorSigchainNotRunning()) public async addClaim( claimData: ClaimData, + tran?: DBTransaction, ): Promise<[ClaimId, ClaimEncoded]> { - return await this._transaction(async () => { - const prevSequenceNumber = await this.getSequenceNumber(); - const newSequenceNumber = prevSequenceNumber + 1; - - const claim = await this.createClaim({ - hPrev: await this.getHashPrevious(), - seq: newSequenceNumber, - data: claimData, - }); - - // Add the claim to the sigchain database, and update the sequence number - const claimId = this.generateClaimId(); - const ops: Array = [ - { - type: 'put', - domain: this.sigchainClaimsDbDomain, - key: claimId.toBuffer(), - value: claim, - }, - { - type: 'put', - domain: this.sigchainMetadataDbDomain, - key: this.sequenceNumberKey, - value: newSequenceNumber, - }, - ]; - await this.db.batch(ops); - return [claimId, claim]; + const claimId = this.generateClaimId(); + const claimIdPath = [...this.sigchainClaimsDbPath, claimId.toBuffer()]; + const sequenceNumberPath = [ + ...this.sigchainMetadataDbPath, + this.sequenceNumberKey, + ]; + if (tran == null) { + return this.withTransactionF( + claimIdPath, + sequenceNumberPath, + async (tran) => this.addClaim(claimData, tran), + ); + } + const prevSequenceNumber = await this.getSequenceNumber(tran); + const newSequenceNumber = prevSequenceNumber + 1; + const claim = await this.createClaim({ + hPrev: await this.getHashPrevious(tran), + seq: newSequenceNumber, + data: claimData, }); + // Add the claim to the sigchain database, and update the sequence number + await tran.put(claimIdPath, claim); + await tran.put(sequenceNumberPath, newSequenceNumber); + return [claimId, claim]; } /** @@ -261,34 +215,35 @@ class Sigchain { * an exception could be thrown. */ @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async addExistingClaim(claim: ClaimEncoded): Promise { - await this._transaction(async () => { - const decodedClaim = claimsUtils.decodeClaim(claim); - const prevSequenceNumber = await this.getSequenceNumber(); - const expectedSequenceNumber = prevSequenceNumber + 1; - // Ensure the sequence number and hash are correct before appending - if (decodedClaim.payload.seq !== expectedSequenceNumber) { - throw new sigchainErrors.ErrorSigchainInvalidSequenceNum(); - } - if (decodedClaim.payload.hPrev !== (await this.getHashPrevious())) { - throw new sigchainErrors.ErrorSigchainInvalidHash(); - } - const ops: Array = [ - { - type: 'put', - domain: this.sigchainClaimsDbDomain, - key: this.generateClaimId().toBuffer(), - value: claim, - }, - { - type: 'put', - domain: this.sigchainMetadataDbDomain, - key: this.sequenceNumberKey, - value: expectedSequenceNumber, - }, - ]; - await this.db.batch(ops); - }); + public async addExistingClaim( + claim: ClaimEncoded, + tran?: DBTransaction, + ): Promise { + const claimId = this.generateClaimId(); + const claimIdPath = [...this.sigchainClaimsDbPath, claimId.toBuffer()]; + const sequenceNumberPath = [ + ...this.sigchainMetadataDbPath, + this.sequenceNumberKey, + ]; + if (tran == null) { + return this.withTransactionF( + claimIdPath, + sequenceNumberPath, + async (tran) => this.addExistingClaim(claim, tran), + ); + } + const decodedClaim = claimsUtils.decodeClaim(claim); + const prevSequenceNumber = await this.getSequenceNumber(tran); + const expectedSequenceNumber = prevSequenceNumber + 1; + // Ensure the sequence number and hash are correct before appending + if (decodedClaim.payload.seq !== expectedSequenceNumber) { + throw new sigchainErrors.ErrorSigchainInvalidSequenceNum(); + } + if (decodedClaim.payload.hPrev !== (await this.getHashPrevious(tran))) { + throw new sigchainErrors.ErrorSigchainInvalidHash(); + } + await tran.put(claimIdPath, claim); + await tran.put(sequenceNumberPath, expectedSequenceNumber); } /** @@ -298,19 +253,27 @@ class Sigchain { @ready(new sigchainErrors.ErrorSigchainNotRunning()) public async createIntermediaryClaim( claimData: ClaimData, + tran?: DBTransaction, ): Promise { - return await this._transaction(async () => { - const claim = await this.createClaim({ - hPrev: await this.getHashPrevious(), - seq: (await this.getSequenceNumber()) + 1, - data: claimData, - }); - const intermediaryClaim: ClaimIntermediary = { - payload: claim.payload, - signature: claim.signatures[0], - }; - return intermediaryClaim; + const sequenceNumberPath = [ + ...this.sigchainMetadataDbPath, + this.sequenceNumberKey, + ]; + if (tran == null) { + return this.withTransactionF(sequenceNumberPath, async (tran) => + this.createIntermediaryClaim(claimData, tran), + ); + } + const claim = await this.createClaim({ + hPrev: await this.getHashPrevious(tran), + seq: (await this.getSequenceNumber(tran)) + 1, + data: claimData, }); + const intermediaryClaim: ClaimIntermediary = { + payload: claim.payload, + signature: claim.signatures[0], + }; + return intermediaryClaim; } /** @@ -320,20 +283,18 @@ class Sigchain { * claimUtils.decodeClaim() to decode each claim. */ @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async getChainData(): Promise { - return await this._transaction(async () => { - const chainData: ChainDataEncoded = {}; - for await (const o of this.sigchainClaimsDb.createReadStream()) { - const claimId = IdInternal.fromBuffer((o as any).key); - const encryptedClaim = (o as any).value; - const claim = await this.db.deserializeDecrypt( - encryptedClaim, - false, - ); - chainData[claimsUtils.encodeClaimId(claimId)] = claim; - } - return chainData; - }); + public async getChainData(tran?: DBTransaction): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => this.getChainData(tran)); + } + const chainData: ChainDataEncoded = {}; + const readIterator = tran.iterator({}, [...this.sigchainClaimsDbPath]); + for await (const [key, value] of readIterator) { + const claimId = IdInternal.fromBuffer(key); + const claim = dbUtils.deserialize(value); + chainData[claimsUtils.encodeClaimId(claimId)] = claim; + } + return chainData; } /** @@ -345,22 +306,25 @@ class Sigchain { * requesting client. */ @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async getClaims(claimType: ClaimType): Promise> { - return await this._transaction(async () => { - const relevantClaims: Array = []; - for await (const o of this.sigchainClaimsDb.createReadStream()) { - const data = (o as any).value; - const claim = await this.db.deserializeDecrypt( - data, - false, - ); - const decodedClaim = claimsUtils.decodeClaim(claim); - if (decodedClaim.payload.data.type === claimType) { - relevantClaims.push(claim); - } + public async getClaims( + claimType: ClaimType, + tran?: DBTransaction, + ): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getClaims(claimType, tran), + ); + } + const relevantClaims: Array = []; + const readIterator = tran.iterator({}, [...this.sigchainClaimsDbPath]); + for await (const [, value] of readIterator) { + const claim = dbUtils.deserialize(value); + const decodedClaim = claimsUtils.decodeClaim(claim); + if (decodedClaim.payload.data.type === claimType) { + relevantClaims.push(claim); } - return relevantClaims; - }); + } + return relevantClaims; } /** @@ -369,37 +333,33 @@ class Sigchain { * @returns previous sequence number */ @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async getSequenceNumber(): Promise { - return await this._transaction(async () => { - const sequenceNumber = await this.db.get( - this.sigchainMetadataDbDomain, - this.sequenceNumberKey, - ); - // Should never be reached: getSigchainDb() has a check whether sigchain - // has been started (where the sequence number is initialised) - if (sequenceNumber === undefined) { - throw new sigchainErrors.ErrorSigchainSequenceNumUndefined(); - } - return sequenceNumber; - }); + protected async getSequenceNumber(tran: DBTransaction): Promise { + const sequenceNumber = await tran.get([ + ...this.sigchainMetadataDbPath, + this.sequenceNumberKey, + ]); + // Should never be reached: getSigchainDb() has a check whether sigchain + // has been started (where the sequence number is initialised) + if (sequenceNumber === undefined) { + throw new sigchainErrors.ErrorSigchainSequenceNumUndefined(); + } + return sequenceNumber; } /** * Helper function to compute the hash of the previous claim. */ @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async getHashPrevious(): Promise { - return await this._transaction(async () => { - const prevSequenceNumber = await this.getLatestClaimId(); - if (prevSequenceNumber == null) { - // If no other claims, then null - return null; - } else { - // Otherwise, create a hash of the previous claim - const previousClaim = await this.getClaim(prevSequenceNumber); - return claimsUtils.hashClaim(previousClaim); - } - }); + protected async getHashPrevious(tran: DBTransaction): Promise { + const prevSequenceNumber = await this.getLatestClaimId(tran); + if (prevSequenceNumber == null) { + // If no other claims, then null + return null; + } else { + // Otherwise, create a hash of the previous claim + const previousClaim = await this.getClaim(prevSequenceNumber, tran); + return claimsUtils.hashClaim(previousClaim); + } } /** @@ -408,59 +368,57 @@ class Sigchain { * (otherwise, if you want to check for existence, just use getSigchainDb() * and check if returned value is undefined). * @param claimId the ClaimId of the claim to retrieve + * @param tran * @returns the claim (a JWS) */ @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async getClaim(claimId: ClaimId): Promise { - return await this._transaction(async () => { - const claim = await this.db.get( - this.sigchainClaimsDbDomain, - claimId.toBuffer(), + public async getClaim( + claimId: ClaimId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getClaim(claimId, tran), ); - if (claim == null) { - throw new sigchainErrors.ErrorSigchainClaimUndefined(); - } - return claim; - }); + } + const claim = await tran.get([ + ...this.sigchainClaimsDbPath, + claimId.toBuffer(), + ]); + if (claim == null) { + throw new sigchainErrors.ErrorSigchainClaimUndefined(); + } + return claim; } @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async getSeqMap(): Promise> { + public async getSeqMap( + tran?: DBTransaction, + ): Promise> { + if (tran == null) { + return this.withTransactionF(async (tran) => this.getSeqMap(tran)); + } const map: Record = {}; - const claimStream = this.sigchainClaimsDb.createKeyStream(); + const claimStream = tran.iterator({}, [...this.sigchainClaimsDbPath]); let seq = 1; - for await (const o of claimStream) { - map[seq] = IdInternal.fromBuffer(o as Buffer); + for await (const [key] of claimStream) { + map[seq] = IdInternal.fromBuffer(key); seq++; } return map; } - @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async clearDB() { - await this.sigchainDb.clear(); - - await this._transaction(async () => { - await this.db.put( - this.sigchainMetadataDbDomain, - this.sequenceNumberKey, - 0, - ); - }); - } - - protected async getLatestClaimId(): Promise { - return await this._transaction(async () => { - let latestId: ClaimId | undefined; - const keyStream = this.sigchainClaimsDb.createKeyStream({ - limit: 1, - reverse: true, - }); - for await (const o of keyStream) { - latestId = IdInternal.fromBuffer(o as Buffer); - } - return latestId; - }); + protected async getLatestClaimId( + tran: DBTransaction, + ): Promise { + let latestId: ClaimId | undefined; + const keyStream = tran.iterator({ limit: 1, reverse: true }, [ + ...this.sigchainClaimsDbPath, + ]); + for await (const [key] of keyStream) { + latestId = IdInternal.fromBuffer(key); + } + return latestId; } } diff --git a/src/sigchain/errors.ts b/src/sigchain/errors.ts index 254c7fef6..0d839c490 100644 --- a/src/sigchain/errors.ts +++ b/src/sigchain/errors.ts @@ -1,26 +1,45 @@ -import { ErrorPolykey } from '../errors'; +import { ErrorPolykey, sysexits } from '../errors'; -class ErrorSigchain extends ErrorPolykey {} +class ErrorSigchain extends ErrorPolykey {} -class ErrorSigchainRunning extends ErrorSigchain {} +class ErrorSigchainRunning extends ErrorSigchain { + static description = 'Sigchain is running'; + exitCode = sysexits.USAGE; +} -class ErrorSigchainNotRunning extends ErrorSigchain {} +class ErrorSigchainNotRunning extends ErrorSigchain { + static description = 'Sigchain is not running'; + exitCode = sysexits.USAGE; +} -class ErrorSigchainDestroyed extends ErrorSigchain {} +class ErrorSigchainDestroyed extends ErrorSigchain { + static description = 'Sigchain is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorSigchainSequenceNumUndefined extends ErrorSigchain {} +class ErrorSigchainSequenceNumUndefined extends ErrorSigchain { + static description = 'Invalid database state'; + exitCode = sysexits.IOERR; +} -class ErrorSigchainClaimUndefined extends ErrorSigchain {} +class ErrorSigchainClaimUndefined extends ErrorSigchain { + static description = 'Could not retrieve claim'; + exitCode = sysexits.USAGE; +} -class ErrorSigchainInvalidSequenceNum extends ErrorSigchain {} +class ErrorSigchainInvalidSequenceNum extends ErrorSigchain { + static description = 'Claim has invalid sequence number'; + exitCode = sysexits.USAGE; +} -class ErrorSigchainInvalidHash extends ErrorSigchain {} +class ErrorSigchainInvalidHash extends ErrorSigchain { + static description = 'Claim has invalid hash'; + exitCode = sysexits.USAGE; +} -class ErrorSighainClaimVerificationFailed extends ErrorSigchain {} +class ErrorSigchainDecrypt extends ErrorSigchain {} -class ErrorSigchainDecrypt extends ErrorSigchain {} - -class ErrorSigchainParse extends ErrorSigchain {} +class ErrorSigchainParse extends ErrorSigchain {} export { ErrorSigchainRunning, @@ -30,7 +49,6 @@ export { ErrorSigchainClaimUndefined, ErrorSigchainInvalidSequenceNum, ErrorSigchainInvalidHash, - ErrorSighainClaimVerificationFailed, ErrorSigchainDecrypt, ErrorSigchainParse, }; diff --git a/src/status/Status.ts b/src/status/Status.ts index 4569f1ed9..01647736c 100644 --- a/src/status/Status.ts +++ b/src/status/Status.ts @@ -112,10 +112,13 @@ class Status { return; } throw new statusErrors.ErrorStatusRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } while (!lock(statusFile.fd)) { @@ -126,10 +129,13 @@ class Status { statusData = (await statusFile.readFile('utf-8')).trim(); } catch (e) { throw new statusErrors.ErrorStatusRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } if (statusData === '') { @@ -139,13 +145,15 @@ class Status { try { statusInfo = JSON.parse(statusData, this.statusReviver); } catch (e) { - throw new statusErrors.ErrorStatusParse('JSON parsing failed'); + throw new statusErrors.ErrorStatusParse('JSON parsing failed', { + cause: e, + }); } if (!statusUtils.statusValidate(statusInfo)) { throw new statusErrors.ErrorStatusParse( 'StatusInfo validation failed', { - errors: statusUtils.statusValidate.errors, + data: { errors: statusUtils.statusValidate.errors }, }, ); } @@ -182,10 +190,13 @@ class Status { ); } catch (e) { throw new statusErrors.ErrorStatusWrite(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } finally { @@ -207,10 +218,13 @@ class Status { statusFile = await this.fs.promises.open(this.statusPath, 'r+'); } catch (e) { throw new statusErrors.ErrorStatusRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } while (!lock(statusFile.fd)) { @@ -221,23 +235,28 @@ class Status { statusData = (await statusFile.readFile('utf-8')).trim(); } catch (e) { throw new statusErrors.ErrorStatusRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } let statusInfo; try { statusInfo = JSON.parse(statusData, this.statusReviver); } catch (e) { - throw new statusErrors.ErrorStatusParse('JSON parsing failed'); + throw new statusErrors.ErrorStatusParse('JSON parsing failed', { + cause: e, + }); } if (!statusUtils.statusValidate(statusInfo)) { throw new statusErrors.ErrorStatusParse( 'StatusInfo validation failed', { - errors: statusUtils.statusValidate.errors, + data: { errors: statusUtils.statusValidate.errors }, }, ); } @@ -256,10 +275,13 @@ class Status { ); } catch (e) { throw new statusErrors.ErrorStatusWrite(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } return statusInfo; @@ -299,7 +321,7 @@ class Status { ); } catch (e) { if (e instanceof errors.ErrorUtilsPollTimeout) { - throw new errors.ErrorStatusTimeout(); + throw new errors.ErrorStatusTimeout(e.message, { cause: e }); } throw e; } diff --git a/src/status/errors.ts b/src/status/errors.ts index 22a2bea08..a56192557 100644 --- a/src/status/errors.ts +++ b/src/status/errors.ts @@ -1,36 +1,39 @@ import { ErrorPolykey, sysexits } from '../errors'; -class ErrorStatus extends ErrorPolykey {} +class ErrorStatus extends ErrorPolykey {} -class ErrorStatusNotRunning extends ErrorStatus {} +class ErrorStatusNotRunning extends ErrorStatus { + static description = 'Status is not running'; + exitCode = sysexits.USAGE; +} -class ErrorStatusLocked extends ErrorStatus { - description = 'Status is locked by another process'; +class ErrorStatusLocked extends ErrorStatus { + static description = 'Status is locked by another process'; exitCode = sysexits.TEMPFAIL; } -class ErrorStatusRead extends ErrorStatus { - description = 'Failed to read status info'; +class ErrorStatusRead extends ErrorStatus { + static description = 'Failed to read status info'; exitCode = sysexits.IOERR; } -class ErrorStatusWrite extends ErrorStatus { - description = 'Failed to write status info'; +class ErrorStatusWrite extends ErrorStatus { + static description = 'Failed to write status info'; exitCode = sysexits.IOERR; } -class ErrorStatusLiveUpdate extends ErrorStatus { - description = 'Failed to update LIVE status info'; +class ErrorStatusLiveUpdate extends ErrorStatus { + static description = 'Failed to update LIVE status info'; exitCode = sysexits.USAGE; } -class ErrorStatusParse extends ErrorStatus { - description = 'Failed to parse status info'; +class ErrorStatusParse extends ErrorStatus { + static description = 'Failed to parse status info'; exitCode = sysexits.CONFIG; } -class ErrorStatusTimeout extends ErrorStatus { - description = 'Poll timed out'; +class ErrorStatusTimeout extends ErrorStatus { + static description = 'Poll timed out'; exitCode = sysexits.TEMPFAIL; } diff --git a/src/types.ts b/src/types.ts index b09954b32..8fba1fc08 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,6 +12,11 @@ type POJO = { [key: string]: any }; */ type Opaque = T & { __TYPE__: K }; +/** + * Non-empty array + */ +type NonEmptyArray = [T, ...T[]]; + /** * Allows extension of constructors that use POJOs */ @@ -75,6 +80,7 @@ type FileHandle = fs.promises.FileHandle; export type { POJO, Opaque, + NonEmptyArray, AbstractConstructorParameters, Initial, InitialParameters, diff --git a/src/utils/context.ts b/src/utils/context.ts deleted file mode 100644 index d4102debc..000000000 --- a/src/utils/context.ts +++ /dev/null @@ -1,75 +0,0 @@ -type ResourceAcquire = () => Promise< - readonly [ResourceRelease, Resource?] ->; - -type ResourceRelease = () => Promise; - -type Resources[]> = { - [K in keyof T]: T[K] extends ResourceAcquire ? R : never; -}; - -/** - * Make sure to explicitly declare or cast `acquires` as a tuple using `[ResourceAcquire...]` or `as const` - */ -async function withF< - ResourceAcquires extends - | readonly [ResourceAcquire] - | readonly ResourceAcquire[], - T, ->( - acquires: ResourceAcquires, - f: (resources: Resources) => Promise, -): Promise { - const releases: Array = []; - const resources: Array = []; - try { - for (const acquire of acquires) { - const [release, resource] = await acquire(); - releases.push(release); - resources.push(resource); - } - return await f(resources as unknown as Resources); - } finally { - releases.reverse(); - for (const release of releases) { - await release(); - } - } -} - -/** - * Make sure to explicitly declare or cast `acquires` as a tuple using `[ResourceAcquire...]` or `as const` - */ -async function* withG< - ResourceAcquires extends - | readonly [ResourceAcquire] - | readonly ResourceAcquire[], - T = unknown, - TReturn = any, - TNext = unknown, ->( - acquires: ResourceAcquires, - g: ( - resources: Resources, - ) => AsyncGenerator, -): AsyncGenerator { - const releases: Array = []; - const resources: Array = []; - try { - for (const acquire of acquires) { - const [release, resource] = await acquire(); - releases.push(release); - resources.push(resource); - } - return yield* g(resources as unknown as Resources); - } finally { - releases.reverse(); - for (const release of releases) { - await release(); - } - } -} - -export { withF, withG }; - -export type { ResourceAcquire, ResourceRelease }; diff --git a/src/utils/errors.ts b/src/utils/errors.ts index af54ffa86..23ea67744 100644 --- a/src/utils/errors.ts +++ b/src/utils/errors.ts @@ -1,25 +1,25 @@ import sysexits from './sysexits'; import ErrorPolykey from '../ErrorPolykey'; -class ErrorUtils extends ErrorPolykey {} +class ErrorUtils extends ErrorPolykey {} /** * This is a special error that is only used for absurd situations * Intended to placate typescript so that unreachable code type checks * If this is thrown, this means there is a bug in the code */ -class ErrorUtilsUndefinedBehaviour extends ErrorUtils { - description = 'You should never see this error'; +class ErrorUtilsUndefinedBehaviour extends ErrorUtils { + static description = 'You should never see this error'; exitCode = sysexits.SOFTWARE; } -class ErrorUtilsPollTimeout extends ErrorUtils { - description = 'Poll timed out'; +class ErrorUtilsPollTimeout extends ErrorUtils { + static description = 'Poll timed out'; exitCode = sysexits.TEMPFAIL; } -class ErrorUtilsNodePath extends ErrorUtils { - description = 'Cannot derive default node path from unknown platform'; +class ErrorUtilsNodePath extends ErrorUtils { + static description = 'Cannot derive default node path from unknown platform'; exitCode = sysexits.USAGE; } diff --git a/src/utils/index.ts b/src/utils/index.ts index cbb38a8be..f50908aca 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,6 +1,4 @@ export { default as sysexits } from './sysexits'; -export * from './locks'; -export * from './context'; export * from './utils'; export * from './matchers'; export * from './binary'; diff --git a/src/utils/locks.ts b/src/utils/locks.ts deleted file mode 100644 index eb6f95245..000000000 --- a/src/utils/locks.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { MutexInterface } from 'async-mutex'; -import { Mutex } from 'async-mutex'; - -/** - * Single threaded write-preferring read write lock - */ -class RWLock { - protected readersLock: Mutex = new Mutex(); - protected writersLock: Mutex = new Mutex(); - protected readersRelease: MutexInterface.Releaser; - protected readerCountBlocked: number = 0; - protected _readerCount: number = 0; - protected _writerCount: number = 0; - - public get readerCount(): number { - return this._readerCount + this.readerCountBlocked; - } - - public get writerCount(): number { - return this._writerCount; - } - - public async withRead(f: () => Promise): Promise { - const release = await this.acquireRead(); - try { - return await f(); - } finally { - release(); - } - } - - public async withWrite(f: () => Promise): Promise { - const release = await this.acquireWrite(); - try { - return await f(); - } finally { - release(); - } - } - - public async acquireRead(): Promise<() => void> { - if (this._writerCount > 0) { - ++this.readerCountBlocked; - await this.writersLock.waitForUnlock(); - --this.readerCountBlocked; - } - const readerCount = ++this._readerCount; - // The first reader locks - if (readerCount === 1) { - this.readersRelease = await this.readersLock.acquire(); - } - return () => { - const readerCount = --this._readerCount; - // The last reader unlocks - if (readerCount === 0) { - this.readersRelease(); - } - }; - } - - public async acquireWrite(): Promise<() => void> { - ++this._writerCount; - const writersRelease = await this.writersLock.acquire(); - this.readersRelease = await this.readersLock.acquire(); - return () => { - this.readersRelease(); - writersRelease(); - --this._writerCount; - }; - } - - public isLocked(): boolean { - return this.readersLock.isLocked() || this.writersLock.isLocked(); - } - - public async waitForUnlock(): Promise { - await Promise.all([ - this.readersLock.waitForUnlock(), - this.writersLock.waitForUnlock(), - ]); - return; - } -} - -export { RWLock }; diff --git a/src/validation/errors.ts b/src/validation/errors.ts index e918ce38b..da01aff34 100644 --- a/src/validation/errors.ts +++ b/src/validation/errors.ts @@ -1,12 +1,12 @@ -import { CustomError } from 'ts-custom-error'; +import { AbstractError } from '@matrixai/errors'; import { ErrorPolykey, sysexits } from '../errors'; /** * Generic error containing all parsing errors that occurred during * execution. */ -class ErrorValidation extends ErrorPolykey { - description = 'Input data failed validation'; +class ErrorValidation extends ErrorPolykey { + static description = 'Input data failed validation'; exitCode = sysexits.DATAERR; public errors: Array; constructor(message, data) { @@ -51,13 +51,12 @@ class ErrorValidation extends ErrorPolykey { * While JS allows us to throw POJOs directly, having a nominal type * is easier to check against */ -class ErrorParse extends CustomError { +class ErrorParse extends AbstractError { + static description: string = 'Failed to parse data into valid format'; + exitCode = sysexits.DATAERR; public keyPath: Array; public value: any; public context: object; - constructor(message?: string) { - super(message); - } } export { ErrorValidation, ErrorParse }; diff --git a/src/vaults/VaultInternal.ts b/src/vaults/VaultInternal.ts index 63611b1a8..ae2adf6cf 100644 --- a/src/vaults/VaultInternal.ts +++ b/src/vaults/VaultInternal.ts @@ -1,6 +1,6 @@ import type { ReadCommitResult } from 'isomorphic-git'; import type { EncryptedFS } from 'encryptedfs'; -import type { DB, DBDomain, DBLevel } from '@matrixai/db'; +import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; import type { CommitId, CommitLog, @@ -15,7 +15,6 @@ import type { import type KeyManager from '../keys/KeyManager'; import type { NodeId, NodeIdEncoded } from '../nodes/types'; import type NodeConnectionManager from '../nodes/NodeConnectionManager'; -import type { ResourceAcquire } from '../utils/context'; import type GRPCClientAgent from '../agent/GRPCClientAgent'; import type { POJO } from '../types'; import path from 'path'; @@ -26,13 +25,13 @@ import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; +import { withF, withG } from '@matrixai/resources'; +import { RWLockWriter } from '@matrixai/async-locks'; import * as vaultsErrors from './errors'; import * as vaultsUtils from './utils'; import { tagLast } from './types'; import * as nodesUtils from '../nodes/utils'; import * as validationUtils from '../validation/utils'; -import { withF, withG } from '../utils/context'; -import { RWLock } from '../utils/locks'; import * as vaultsPB from '../proto/js/polykey/v1/vaults/vaults_pb'; import { never } from '../utils/utils'; @@ -51,35 +50,50 @@ class VaultInternal { vaultId, vaultName, db, - vaultsDb, - vaultsDbDomain, + vaultsDbPath, keyManager, efs, logger = new Logger(this.name), fresh = false, + tran, }: { vaultId: VaultId; vaultName?: VaultName; db: DB; - vaultsDb: DBLevel; - vaultsDbDomain: DBDomain; + vaultsDbPath: LevelPath; keyManager: KeyManager; efs: EncryptedFS; logger?: Logger; fresh?: boolean; + tran?: DBTransaction; }): Promise { + if (tran == null) { + return await db.withTransactionF(async (tran) => + this.createVaultInternal({ + vaultId, + vaultName, + db, + vaultsDbPath, + keyManager, + efs, + logger, + fresh, + tran, + }), + ); + } + const vaultIdEncoded = vaultsUtils.encodeVaultId(vaultId); logger.info(`Creating ${this.name} - ${vaultIdEncoded}`); const vault = new VaultInternal({ vaultId, db, - vaultsDb, - vaultsDbDomain, + vaultsDbPath, keyManager, efs, logger, }); - await vault.start({ fresh, vaultName }); + await vault.start({ fresh, vaultName, tran }); logger.info(`Created ${this.name} - ${vaultIdEncoded}`); return vault; } @@ -89,31 +103,47 @@ class VaultInternal { targetVaultNameOrId, vaultId, db, - vaultsDb, - vaultsDbDomain, + vaultsDbPath, keyManager, nodeConnectionManager, efs, logger = new Logger(this.name), + tran, }: { targetNodeId: NodeId; targetVaultNameOrId: VaultId | VaultName; vaultId: VaultId; db: DB; - vaultsDb: DBLevel; - vaultsDbDomain: DBDomain; + vaultsDbPath: LevelPath; efs: EncryptedFS; keyManager: KeyManager; nodeConnectionManager: NodeConnectionManager; logger?: Logger; + tran?: DBTransaction; }): Promise { + if (tran == null) { + return await db.withTransactionF(async (tran) => + this.cloneVaultInternal({ + targetNodeId, + targetVaultNameOrId, + vaultId, + db, + vaultsDbPath, + keyManager, + nodeConnectionManager, + efs, + logger, + tran, + }), + ); + } + const vaultIdEncoded = vaultsUtils.encodeVaultId(vaultId); logger.info(`Cloning ${this.name} - ${vaultIdEncoded}`); const vault = new VaultInternal({ vaultId, db, - vaultsDb, - vaultsDbDomain, + vaultsDbPath, keyManager, efs, logger, @@ -160,11 +190,10 @@ class VaultInternal { throw e; } - await vault.start({ vaultName }); + await vault.start({ vaultName, tran }); // Setting the remote in the metadata - await vault.db.put( - vault.vaultMetadataDbDomain, - VaultInternal.remoteKey, + await tran.put( + [...vault.vaultMetadataDbPath, VaultInternal.remoteKey], remote, ); logger.info(`Cloned ${this.name} - ${vaultIdEncoded}`); @@ -182,39 +211,29 @@ class VaultInternal { protected logger: Logger; protected db: DB; - protected vaultsDbDomain: DBDomain; - protected vaultsDb: DBLevel; - protected vaultMetadataDbDomain: DBDomain; - protected vaultMetadataDb: DBLevel; + protected vaultsDbPath: LevelPath; + protected vaultMetadataDbPath: LevelPath; protected keyManager: KeyManager; - protected vaultsNamesDomain: DBDomain; + protected vaultsNamesPath: LevelPath; protected efs: EncryptedFS; protected efsVault: EncryptedFS; - protected lock: RWLock = new RWLock(); - - public readLock: ResourceAcquire = async () => { - const release = await this.lock.acquireRead(); - return [async () => release()]; - }; + protected lock: RWLockWriter = new RWLockWriter(); - public writeLock: ResourceAcquire = async () => { - const release = await this.lock.acquireWrite(); - return [async () => release()]; - }; + public getLock(): RWLockWriter { + return this.lock; + } constructor({ vaultId, db, - vaultsDbDomain, - vaultsDb, + vaultsDbPath, keyManager, efs, logger, }: { vaultId: VaultId; db: DB; - vaultsDbDomain: DBDomain; - vaultsDb: DBLevel; + vaultsDbPath: LevelPath; keyManager: KeyManager; efs: EncryptedFS; logger: Logger; @@ -226,8 +245,7 @@ class VaultInternal { this.vaultDataDir = path.join(vaultIdEncoded, 'data'); this.vaultGitDir = path.join(vaultIdEncoded, '.git'); this.db = db; - this.vaultsDbDomain = vaultsDbDomain; - this.vaultsDb = vaultsDb; + this.vaultsDbPath = vaultsDbPath; this.keyManager = keyManager; this.efs = efs; } @@ -236,27 +254,38 @@ class VaultInternal { * * @param fresh Clears all state before starting * @param vaultName Name of the vault, Only used when creating a new vault + * @param tran */ public async start({ fresh = false, vaultName, + tran, }: { fresh?: boolean; vaultName?: VaultName; + tran?: DBTransaction; } = {}): Promise { + if (tran == null) { + return await this.db.withTransactionF(async (tran) => + this.start_(fresh, tran, vaultName), + ); + } + return await this.start_(fresh, tran, vaultName); + } + + protected async start_( + fresh: boolean, + tran: DBTransaction, + vaultName?: VaultName, + ) { this.logger.info( `Starting ${this.constructor.name} - ${this.vaultIdEncoded}`, ); - this.vaultMetadataDbDomain = [...this.vaultsDbDomain, this.vaultIdEncoded]; - this.vaultsNamesDomain = [...this.vaultsDbDomain, 'names']; - this.vaultMetadataDb = await this.db.level( - this.vaultIdEncoded, - this.vaultsDb, - ); + this.vaultMetadataDbPath = [...this.vaultsDbPath, this.vaultIdEncoded]; + this.vaultsNamesPath = [...this.vaultsDbPath, 'names']; // Let's backup any metadata - if (fresh) { - await this.vaultMetadataDb.clear(); + await tran.clear(this.vaultMetadataDbPath); try { await this.efs.rmdir(this.vaultIdEncoded, { recursive: true, @@ -270,15 +299,15 @@ class VaultInternal { await this.mkdirExists(this.vaultIdEncoded); await this.mkdirExists(this.vaultDataDir); await this.mkdirExists(this.vaultGitDir); - await this.setupMeta({ vaultName }); - await this.setupGit(); + await this.setupMeta({ vaultName, tran }); + await this.setupGit(tran); this.efsVault = await this.efs.chroot(this.vaultDataDir); this.logger.info( `Started ${this.constructor.name} - ${this.vaultIdEncoded}`, ); } - private async mkdirExists(directory: string) { + protected async mkdirExists(directory: string) { try { await this.efs.mkdir(directory, { recursive: true }); } catch (e) { @@ -297,12 +326,20 @@ class VaultInternal { ); } - public async destroy(): Promise { + public async destroy(tran?: DBTransaction): Promise { + if (tran == null) { + return await this.db.withTransactionF(async (tran) => + this.destroy_(tran), + ); + } + return await this.destroy_(tran); + } + + protected async destroy_(tran: DBTransaction) { this.logger.info( `Destroying ${this.constructor.name} - ${this.vaultIdEncoded}`, ); - const vaultDb = await this.db.level(this.vaultIdEncoded, this.vaultsDb); - await vaultDb.clear(); + await tran.clear(this.vaultMetadataDbPath); try { await this.efs.rmdir(this.vaultIdEncoded, { recursive: true, @@ -376,7 +413,9 @@ class VaultInternal { e instanceof git.Errors.NotFoundError || e instanceof git.Errors.CommitNotFetchedError ) { - throw new vaultsErrors.ErrorVaultReferenceMissing(); + throw new vaultsErrors.ErrorVaultReferenceMissing(e.message, { + cause: e, + }); } throw e; } @@ -384,7 +423,7 @@ class VaultInternal { @ready(new vaultsErrors.ErrorVaultNotRunning()) public async readF(f: (fs: FileSystemReadable) => Promise): Promise { - return withF([this.readLock], async () => { + return withF([this.lock.read()], async () => { return await f(this.efsVault); }); } @@ -394,7 +433,7 @@ class VaultInternal { g: (fs: FileSystemReadable) => AsyncGenerator, ): AsyncGenerator { const efsVault = this.efsVault; - return withG([this.readLock], async function* () { + return withG([this.lock.read()], async function* () { return yield* g(efsVault); }); } @@ -402,24 +441,28 @@ class VaultInternal { @ready(new vaultsErrors.ErrorVaultNotRunning()) public async writeF( f: (fs: FileSystemWritable) => Promise, + tran?: DBTransaction, ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => this.writeF(f, tran)); + } + // This should really be an internal property // get whether this is remote, and the remote address // if it is, we consider this repo an "attached repo" // this vault is a "mirrored" vault if ( - (await this.db.get( - this.vaultMetadataDbDomain, + (await tran.get([ + ...this.vaultMetadataDbPath, VaultInternal.remoteKey, - )) != null + ])) != null ) { // Mirrored vaults are immutable throw new vaultsErrors.ErrorVaultRemoteDefined(); } - return withF([this.writeLock], async () => { - await this.db.put( - this.vaultMetadataDbDomain, - VaultInternal.dirtyKey, + return withF([this.lock.write()], async () => { + await tran.put( + [...this.vaultMetadataDbPath, VaultInternal.dirtyKey], true, ); try { @@ -431,9 +474,8 @@ class VaultInternal { await this.cleanWorkingDirectory(); throw e; } - await this.db.put( - this.vaultMetadataDbDomain, - VaultInternal.dirtyKey, + await tran.put( + [...this.vaultMetadataDbPath, VaultInternal.dirtyKey], false, ); }); @@ -442,18 +484,25 @@ class VaultInternal { @ready(new vaultsErrors.ErrorVaultNotRunning()) public writeG( g: (fs: FileSystemWritable) => AsyncGenerator, + tran?: DBTransaction, ): AsyncGenerator { + if (tran == null) { + return this.db.withTransactionG((tran) => this.writeG(g, tran)); + } + const efsVault = this.efsVault; - const db = this.db; - const vaultDbDomain = this.vaultMetadataDbDomain; + const vaultMetadataDbPath = this.vaultMetadataDbPath; const createCommit = () => this.createCommit(); const cleanWorkingDirectory = () => this.cleanWorkingDirectory(); - return withG([this.writeLock], async function* () { - if ((await db.get(vaultDbDomain, VaultInternal.remoteKey)) != null) { + return withG([this.lock.write()], async function* () { + if ( + (await tran.get([...vaultMetadataDbPath, VaultInternal.remoteKey])) != + null + ) { // Mirrored vaults are immutable throw new vaultsErrors.ErrorVaultRemoteDefined(); } - await db.put(vaultDbDomain, VaultInternal.dirtyKey, true); + await tran.put([...vaultMetadataDbPath, VaultInternal.dirtyKey], true); let result; // Do what you need to do here, create the commit @@ -470,7 +519,7 @@ class VaultInternal { await cleanWorkingDirectory(); throw e; } - await db.put(vaultDbDomain, VaultInternal.dirtyKey, false); + await tran.put([...vaultMetadataDbPath, VaultInternal.dirtyKey], false); return result; }); } @@ -480,20 +529,33 @@ class VaultInternal { nodeConnectionManager, pullNodeId, pullVaultNameOrId, + tran, }: { nodeConnectionManager: NodeConnectionManager; pullNodeId?: NodeId; pullVaultNameOrId?: VaultId | VaultName; - }) { + tran?: DBTransaction; + }): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.pullVault({ + nodeConnectionManager, + pullNodeId, + pullVaultNameOrId, + tran, + }), + ); + } + // This error flag will contain the error returned by the cloning grpc stream let error; // Keeps track of whether the metadata needs changing to avoid unnecessary db ops // 0 = no change, 1 = change with vault Id, 2 = change with vault name let metaChange = 0; - const remoteInfo = await this.db.get( - this.vaultMetadataDbDomain, + const remoteInfo = await tran.get([ + ...this.vaultMetadataDbPath, VaultInternal.remoteKey, - ); + ]); if (remoteInfo == null) throw new vaultsErrors.ErrorVaultRemoteUndefined(); if (pullNodeId == null) { @@ -528,7 +590,7 @@ class VaultInternal { pullVaultNameOrId!, 'pull', ); - await withF([this.writeLock], async () => { + await withF([this.lock.write()], async () => { await git.pull({ fs: this.efs, http: { request }, @@ -551,7 +613,9 @@ class VaultInternal { if (err instanceof git.Errors.SmartHttpError && error) { throw error; } else if (err instanceof git.Errors.MergeNotSupportedError) { - throw new vaultsErrors.ErrorVaultsMergeConflict(); + throw new vaultsErrors.ErrorVaultsMergeConflict(err.message, { + cause: err, + }); } throw err; } @@ -559,9 +623,8 @@ class VaultInternal { if (metaChange === 2) { remoteInfo.remoteVault = vaultsUtils.encodeVaultId(remoteVaultId); } - await this.db.put( - this.vaultMetadataDbDomain, - VaultInternal.remoteKey, + await tran.put( + [...this.vaultMetadataDbPath, VaultInternal.remoteKey], remoteInfo, ); } @@ -577,8 +640,10 @@ class VaultInternal { */ protected async setupMeta({ vaultName, + tran, }: { vaultName?: VaultName; + tran: DBTransaction; }): Promise { // Setup the vault metadata // and you need to make certain preparations @@ -589,29 +654,27 @@ class VaultInternal { // If this is not existing // setup default vaults db if ( - (await this.db.get( - this.vaultMetadataDbDomain, + (await tran.get([ + ...this.vaultMetadataDbPath, VaultInternal.dirtyKey, - )) == null + ])) == null ) { - await this.db.put( - this.vaultMetadataDbDomain, - VaultInternal.dirtyKey, + await tran.put( + [...this.vaultMetadataDbPath, VaultInternal.dirtyKey], false, ); } // Set up vault Name if ( - (await this.db.get( - this.vaultMetadataDbDomain, + (await tran.get([ + ...this.vaultMetadataDbPath, VaultInternal.nameKey, - )) == null && + ])) == null && vaultName != null ) { - await this.db.put( - this.vaultMetadataDbDomain, - VaultInternal.nameKey, + await tran.put( + [...this.vaultMetadataDbPath, VaultInternal.nameKey], vaultName, ); } @@ -621,7 +684,7 @@ class VaultInternal { // name: string | undefined } - protected async setupGit(): Promise { + protected async setupGit(tran: DBTransaction): Promise { // Initialization is idempotent // It works even with an existing git repository await git.init({ @@ -669,10 +732,10 @@ class VaultInternal { } else { // Checking for dirty if ( - (await this.db.get( - this.vaultMetadataDbDomain, + (await tran.get([ + ...this.vaultMetadataDbPath, VaultInternal.dirtyKey, - )) === true + ])) === true ) { // Force checkout out to the latest commit // This ensures that any uncommitted state is dropped @@ -681,9 +744,8 @@ class VaultInternal { await this.garbageCollectGitObjects(); // Setting dirty back to false - await this.db.put( - this.vaultMetadataDbDomain, - VaultInternal.dirtyKey, + await tran.put( + [...this.vaultMetadataDbPath, VaultInternal.dirtyKey], false, ); } diff --git a/src/vaults/VaultManager.ts b/src/vaults/VaultManager.ts index ed65478f5..2f8fe364f 100644 --- a/src/vaults/VaultManager.ts +++ b/src/vaults/VaultManager.ts @@ -1,4 +1,5 @@ -import type { DB, DBDomain, DBLevel } from '@matrixai/db'; +import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; +import type { ResourceAcquire, ResourceRelease } from '@matrixai/resources'; import type { VaultId, VaultName, @@ -15,9 +16,7 @@ import type NodeConnectionManager from '../nodes/NodeConnectionManager'; import type GestaltGraph from '../gestalts/GestaltGraph'; import type NotificationsManager from '../notifications/NotificationsManager'; import type ACL from '../acl/ACL'; - import type { RemoteInfo } from './VaultInternal'; -import type { ResourceAcquire } from '../utils/context'; import type { VaultAction } from './types'; import path from 'path'; import { PassThrough } from 'readable-stream'; @@ -28,6 +27,8 @@ import { ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { IdInternal } from '@matrixai/id'; +import { withF, withG } from '@matrixai/resources'; +import { RWLockWriter } from '@matrixai/async-locks'; import VaultInternal from './VaultInternal'; import * as vaultsUtils from '../vaults/utils'; import * as vaultsErrors from '../vaults/errors'; @@ -37,8 +38,6 @@ import * as nodesUtils from '../nodes/utils'; import * as keysUtils from '../keys/utils'; import config from '../config'; import { mkdirExists } from '../utils/utils'; -import { RWLock } from '../utils/locks'; -import { withF, withG } from '../utils/context'; import * as utilsPB from '../proto/js/polykey/v1/utils/utils_pb'; /** @@ -48,7 +47,7 @@ type VaultMap = Map< VaultIdString, { vault?: VaultInternal; - lock: RWLock; + lock: RWLockWriter; } >; @@ -59,6 +58,10 @@ type VaultMetadata = { remoteInfo?: RemoteInfo; }; +// TODO: +// - Check all `tran` parameters and evaluate if they need to be optional or not +// - check all uses of gestaltGraph and ACL for passing tran + interface VaultManager extends CreateDestroyStartStop {} @CreateDestroyStartStop( new vaultsErrors.ErrorVaultManagerRunning(), @@ -121,11 +124,9 @@ class VaultManager { protected nodeConnectionManager: NodeConnectionManager; protected gestaltGraph: GestaltGraph; protected notificationsManager: NotificationsManager; - protected vaultsDbDomain: DBDomain = [this.constructor.name]; - protected vaultsDb: DBLevel; - protected vaultsNamesDbDomain: DBDomain = [...this.vaultsDbDomain, 'names']; - protected vaultsNamesDb: DBLevel; - protected vaultsNamesLock: RWLock = new RWLock(); + protected vaultsDbPath: LevelPath = [this.constructor.name]; + protected vaultsNamesDbPath: LevelPath = [this.constructor.name, 'names']; + protected vaultsNamesLock: RWLockWriter = new RWLockWriter(); // VaultId -> VaultMetadata protected vaultMap: VaultMap = new Map(); protected vaultKey: Buffer; @@ -172,50 +173,50 @@ class VaultManager { }: { fresh?: boolean; } = {}): Promise { - try { - this.logger.info(`Starting ${this.constructor.name}`); - const vaultsDb = await this.db.level(this.vaultsDbDomain[0]); - const vaultsNamesDb = await this.db.level( - this.vaultsNamesDbDomain[1], - vaultsDb, - ); - if (fresh) { - await vaultsDb.clear(); - await this.fs.promises.rm(this.vaultsPath, { - force: true, - recursive: true, - }); - } - await mkdirExists(this.fs, this.vaultsPath); - const vaultKey = await this.setupKey(this.keyBits); - let efs; + await this.db.withTransactionF(async (tran) => { try { - efs = await EncryptedFS.createEncryptedFS({ - dbPath: this.efsPath, - dbKey: vaultKey, - logger: this.logger.getChild('EncryptedFileSystem'), - }); - } catch (e) { - if (e instanceof encryptedFsErrors.ErrorEncryptedFSKey) { - throw new vaultsErrors.ErrorVaultManagerKey(); + this.logger.info(`Starting ${this.constructor.name}`); + if (fresh) { + await tran.clear(this.vaultsDbPath); + await this.fs.promises.rm(this.vaultsPath, { + force: true, + recursive: true, + }); } - throw new vaultsErrors.ErrorVaultManagerEFS(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, - }); + await mkdirExists(this.fs, this.vaultsPath); + const vaultKey = await this.setupKey(this.keyBits, tran); + let efs; + try { + efs = await EncryptedFS.createEncryptedFS({ + dbPath: this.efsPath, + dbKey: vaultKey, + logger: this.logger.getChild('EncryptedFileSystem'), + }); + } catch (e) { + if (e instanceof encryptedFsErrors.ErrorEncryptedFSKey) { + throw new vaultsErrors.ErrorVaultManagerKey(e.message, { + cause: e, + }); + } + throw new vaultsErrors.ErrorVaultManagerEFS(e.message, { + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, + }); + } + this.vaultKey = vaultKey; + this.efs = efs; + this.logger.info(`Started ${this.constructor.name}`); + } catch (e) { + this.logger.warn(`Failed Starting ${this.constructor.name}`); + await this.efs?.stop(); + throw e; } - this.vaultsDb = vaultsDb; - this.vaultsNamesDb = vaultsNamesDb; - this.vaultKey = vaultKey; - this.efs = efs; - this.logger.info(`Started ${this.constructor.name}`); - } catch (e) { - this.logger.warn(`Failed Starting ${this.constructor.name}`); - await this.efs?.stop(); - throw e; - } + }); } public async stop(): Promise { @@ -223,7 +224,6 @@ class VaultManager { // Iterate over vaults in memory and destroy them, ensuring that // the working directory commit state is saved - for (const [vaultIdString, vaultAndLock] of this.vaultMap) { const vaultId = IdInternal.fromString(vaultIdString); await withF([this.getWriteLock(vaultId)], async () => { @@ -240,11 +240,8 @@ class VaultManager { public async destroy(): Promise { this.logger.info(`Destroying ${this.constructor.name}`); await this.efs.destroy(); - // If the DB was stopped, the existing sublevel `this.vaultsDb` will not be valid - // Therefore we recreate the sublevel here - const vaultsDb = await this.db.level(this.vaultsDbDomain[0]); // Clearing all vaults db data - await vaultsDb.clear(); + await this.db.clear(this.vaultsDbPath); // Is it necessary to remove the vaults domain? await this.fs.promises.rm(this.vaultsPath, { force: true, @@ -261,29 +258,24 @@ class VaultManager { this.efs.unsetWorkerManager(); } - protected getLock(vaultId: VaultId): RWLock { + public getLock(vaultId: VaultId): RWLockWriter { + // Console.log(new Error(vaultId.toMultibase('base32hex')).stack); const vaultIdString = vaultId.toString() as VaultIdString; const vaultAndLock = this.vaultMap.get(vaultIdString); if (vaultAndLock != null) return vaultAndLock.lock; - const lock = new RWLock(); + const lock = new RWLockWriter(); this.vaultMap.set(vaultIdString, { lock }); return lock; } - protected getReadLock(vaultId: VaultId): ResourceAcquire { + protected getReadLock(vaultId: VaultId): ResourceAcquire { const lock = this.getLock(vaultId); - return async () => { - const release = await lock.acquireRead(); - return [async () => release()]; - }; + return lock.read(); } - protected getWriteLock(vaultId: VaultId): ResourceAcquire { + protected getWriteLock(vaultId: VaultId): ResourceAcquire { const lock = this.getLock(vaultId); - return async () => { - const release = await lock.acquireWrite(); - return [async () => release()]; - }; + return lock.write(); } /** @@ -294,45 +286,51 @@ class VaultManager { // this should actually @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async createVault(vaultName: VaultName): Promise { + public async createVault( + vaultName: VaultName, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.createVault(vaultName, tran), + ); + } // Adding vault to name map const vaultId = await this.generateVaultId(); - await this.vaultsNamesLock.withWrite(async () => { - const vaultIdBuffer = await this.db.get( - this.vaultsNamesDbDomain, - vaultName, + return await this.vaultsNamesLock.withWriteF(async () => { + const vaultIdBuffer = await tran.get( + [...this.vaultsNamesDbPath, vaultName], true, ); // Check if the vault name already exists; if (vaultIdBuffer != null) { throw new vaultsErrors.ErrorVaultsVaultDefined(); } - await this.db.put( - this.vaultsNamesDbDomain, - vaultName, + await tran.put( + [...this.vaultsNamesDbPath, vaultName], vaultId.toBuffer(), true, ); - }); - const lock = new RWLock(); - const vaultIdString = vaultId.toString() as VaultIdString; - this.vaultMap.set(vaultIdString, { lock }); - return await withF([this.getWriteLock(vaultId)], async () => { - // Creating vault - const vault = await VaultInternal.createVaultInternal({ - vaultId, - vaultName, - keyManager: this.keyManager, - efs: this.efs, - logger: this.logger.getChild(VaultInternal.name), - db: this.db, - vaultsDb: this.vaultsDb, - vaultsDbDomain: this.vaultsDbDomain, - fresh: true, + const lock = new RWLockWriter(); + const vaultIdString = vaultId.toString() as VaultIdString; + this.vaultMap.set(vaultIdString, { lock }); + return await withF([this.getWriteLock(vaultId)], async () => { + // Creating vault + const vault = await VaultInternal.createVaultInternal({ + vaultId, + vaultName, + keyManager: this.keyManager, + efs: this.efs, + logger: this.logger.getChild(VaultInternal.name), + db: this.db, + vaultsDbPath: this.vaultsDbPath, + fresh: true, + tran, + }); + // Adding vault to object map + this.vaultMap.set(vaultIdString, { lock, vault }); + return vault.vaultId; }); - // Adding vault to object map - this.vaultMap.set(vaultIdString, { lock, vault }); - return vault.vaultId; }); } @@ -343,26 +341,32 @@ class VaultManager { @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) public async getVaultMeta( vaultId: VaultId, + tran?: DBTransaction, ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.getVaultMeta(vaultId, tran), + ); + } + // First check if the metadata exists const vaultIdEncoded = vaultsUtils.encodeVaultId(vaultId); - const vaultDbDomain = [...this.vaultsDbDomain, vaultIdEncoded]; - const vaultDb = await this.db.level(vaultIdEncoded, this.vaultsDb); + const vaultDbPath: LevelPath = [...this.vaultsDbPath, vaultIdEncoded]; // Return if metadata has no data - if ((await this.db.count(vaultDb)) === 0) return; + if ((await tran.count(vaultDbPath)) === 0) return; // Obtain the metadata; - const dirty = (await this.db.get( - vaultDbDomain, + const dirty = (await tran.get([ + ...vaultDbPath, VaultInternal.dirtyKey, - ))!; - const vaultName = (await this.db.get( - vaultDbDomain, + ]))!; + const vaultName = (await tran.get([ + ...vaultDbPath, VaultInternal.nameKey, - ))!; - const remoteInfo = await this.db.get( - vaultDbDomain, + ]))!; + const remoteInfo = await tran.get([ + ...vaultDbPath, VaultInternal.remoteKey, - ); + ]); return { dirty, vaultName, @@ -375,22 +379,31 @@ class VaultManager { * given vault Id */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async destroyVault(vaultId: VaultId) { - const vaultMeta = await this.getVaultMeta(vaultId); + public async destroyVault( + vaultId: VaultId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.destroyVault(vaultId, tran), + ); + } + + const vaultMeta = await this.getVaultMeta(vaultId, tran); if (vaultMeta == null) return; const vaultName = vaultMeta.vaultName; this.logger.info(`Destroying Vault ${vaultsUtils.encodeVaultId(vaultId)}`); const vaultIdString = vaultId.toString() as VaultIdString; await withF([this.getWriteLock(vaultId)], async () => { - const vault = await this.getVault(vaultId); + const vault = await this.getVault(vaultId, tran); // Destroying vault state and metadata await vault.stop(); - await vault.destroy(); + await vault.destroy(tran); // Removing from map this.vaultMap.delete(vaultIdString); // Removing name->id mapping - await this.vaultsNamesLock.withWrite(async () => { - await this.db.del(this.vaultsNamesDbDomain, vaultName); + await this.vaultsNamesLock.withWriteF(async () => { + await tran.del([...this.vaultsNamesDbPath, vaultName]); }); }); this.logger.info(`Destroyed Vault ${vaultsUtils.encodeVaultId(vaultId)}`); @@ -400,13 +413,22 @@ class VaultManager { * Removes vault from the vault map */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async closeVault(vaultId: VaultId) { - if ((await this.getVaultName(vaultId)) == null) { + public async closeVault( + vaultId: VaultId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.closeVault(vaultId, tran), + ); + } + + if ((await this.getVaultName(vaultId, tran)) == null) { throw new vaultsErrors.ErrorVaultsVaultUndefined(); } const vaultIdString = vaultId.toString() as VaultIdString; await withF([this.getWriteLock(vaultId)], async () => { - const vault = await this.getVault(vaultId); + const vault = await this.getVault(vaultId, tran); await vault.stop(); this.vaultMap.delete(vaultIdString); }); @@ -417,12 +439,19 @@ class VaultManager { * the vaults stored */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async listVaults(): Promise { + public async listVaults(tran?: DBTransaction): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => this.listVaults(tran)); + } + const vaults: VaultList = new Map(); // Stream of vaultName VaultId key value pairs - for await (const vaultNameBuffer of this.vaultsNamesDb.createKeyStream()) { + for await (const [vaultNameBuffer, vaultIdBuffer] of tran.iterator( + undefined, + this.vaultsNamesDbPath, + )) { const vaultName = vaultNameBuffer.toString() as VaultName; - const vaultId = (await this.getVaultId(vaultName))!; + const vaultId = IdInternal.fromBuffer(vaultIdBuffer); vaults.set(vaultName, vaultId); } return vaults; @@ -435,31 +464,37 @@ class VaultManager { public async renameVault( vaultId: VaultId, newVaultName: VaultName, + tran?: DBTransaction, ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.renameVault(vaultId, newVaultName, tran), + ); + } + await withF([this.getWriteLock(vaultId)], async () => { this.logger.info(`Renaming Vault ${vaultsUtils.encodeVaultId(vaultId)}`); // Checking if new name exists - if (await this.getVaultId(newVaultName)) { + if (await this.getVaultId(newVaultName, tran)) { throw new vaultsErrors.ErrorVaultsVaultDefined(); } // Checking if vault exists - const vaultMetadata = await this.getVaultMeta(vaultId); + const vaultMetadata = await this.getVaultMeta(vaultId, tran); if (vaultMetadata == null) { throw new vaultsErrors.ErrorVaultsVaultUndefined(); } const oldVaultName = vaultMetadata.vaultName; // Updating metadata with new name; - const vaultDbDomain = [ - ...this.vaultsDbDomain, + const vaultDbPath = [ + ...this.vaultsDbPath, vaultsUtils.encodeVaultId(vaultId), ]; - await this.db.put(vaultDbDomain, VaultInternal.nameKey, newVaultName); + await tran.put([...vaultDbPath, VaultInternal.nameKey], newVaultName); // Updating name->id map - await this.vaultsNamesLock.withWrite(async () => { - await this.db.del(this.vaultsNamesDbDomain, oldVaultName); - await this.db.put( - this.vaultsNamesDbDomain, - newVaultName, + await this.vaultsNamesLock.withWriteF(async () => { + await tran.del([...this.vaultsNamesDbPath, oldVaultName]); + await tran.put( + [...this.vaultsNamesDbPath, newVaultName], vaultId.toBuffer(), true, ); @@ -471,11 +506,19 @@ class VaultManager { * Retreives the vault Id associated with a vault name */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async getVaultId(vaultName: VaultName): Promise { - return await this.vaultsNamesLock.withWrite(async () => { - const vaultIdBuffer = await this.db.get( - this.vaultsNamesDbDomain, - vaultName, + public async getVaultId( + vaultName: VaultName, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.getVaultId(vaultName, tran), + ); + } + + return await this.vaultsNamesLock.withWriteF(async () => { + const vaultIdBuffer = await tran.get( + [...this.vaultsNamesDbPath, vaultName], true, ); if (vaultIdBuffer == null) return; @@ -487,20 +530,34 @@ class VaultManager { * Retreives the vault name associated with a vault Id */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async getVaultName(vaultId: VaultId): Promise { - const metadata = await this.getVaultMeta(vaultId); + public async getVaultName( + vaultId: VaultId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.getVaultName(vaultId, tran), + ); + } + const metadata = await this.getVaultMeta(vaultId, tran); return metadata?.vaultName; } /** * Returns a dictionary of VaultActions for each node - * @param vaultId */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) public async getVaultPermission( vaultId: VaultId, + tran?: DBTransaction, ): Promise> { - const rawPermissions = await this.acl.getVaultPerm(vaultId); + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.getVaultPermission(vaultId, tran), + ); + } + + const rawPermissions = await this.acl.getVaultPerm(vaultId, tran); const permissions: Record = {}; // Getting the relevant information for (const nodeId in rawPermissions) { @@ -514,14 +571,24 @@ class VaultManager { * gestalt and send a notification to this gestalt */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async shareVault(vaultId: VaultId, nodeId: NodeId): Promise { - const vaultMeta = await this.getVaultMeta(vaultId); - if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined(); + public async shareVault( + vaultId: VaultId, + nodeId: NodeId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.shareVault(vaultId, nodeId, tran), + ); + } + + const vaultMeta = await this.getVaultMeta(vaultId, tran); + if (vaultMeta == null) throw new vaultsErrors.ErrorVaultsVaultUndefined(); // Node Id permissions translated to other nodes in // a gestalt by other domains - await this.gestaltGraph.setGestaltActionByNode(nodeId, 'scan'); - await this.acl.setVaultAction(vaultId, nodeId, 'pull'); - await this.acl.setVaultAction(vaultId, nodeId, 'clone'); + await this.gestaltGraph.setGestaltActionByNode(nodeId, 'scan', tran); + await this.acl.setVaultAction(vaultId, nodeId, 'pull', tran); + await this.acl.setVaultAction(vaultId, nodeId, 'clone', tran); await this.notificationsManager.sendNotification(nodeId, { type: 'VaultShare', vaultId: vaultsUtils.encodeVaultId(vaultId), @@ -538,12 +605,22 @@ class VaultManager { * gestalt */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async unshareVault(vaultId: VaultId, nodeId: NodeId): Promise { - const vaultMeta = await this.getVaultMeta(vaultId); + public async unshareVault( + vaultId: VaultId, + nodeId: NodeId, + tran?: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.unshareVault(vaultId, nodeId, tran), + ); + } + + const vaultMeta = await this.getVaultMeta(vaultId, tran); if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined(); - await this.gestaltGraph.unsetGestaltActionByNode(nodeId, 'scan'); - await this.acl.unsetVaultAction(vaultId, nodeId, 'pull'); - await this.acl.unsetVaultAction(vaultId, nodeId, 'clone'); + await this.gestaltGraph.unsetGestaltActionByNode(nodeId, 'scan', tran); + await this.acl.unsetVaultAction(vaultId, nodeId, 'pull', tran); + await this.acl.unsetVaultAction(vaultId, nodeId, 'clone', tran); } /** @@ -554,9 +631,16 @@ class VaultManager { public async cloneVault( nodeId: NodeId, vaultNameOrId: VaultId | VaultName, + tran?: DBTransaction, ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.cloneVault(nodeId, vaultNameOrId, tran), + ); + } + const vaultId = await this.generateVaultId(); - const lock = new RWLock(); + const lock = new RWLockWriter(); const vaultIdString = vaultId.toString() as VaultIdString; this.vaultMap.set(vaultIdString, { lock }); this.logger.info( @@ -569,23 +653,23 @@ class VaultManager { vaultId, db: this.db, nodeConnectionManager: this.nodeConnectionManager, - vaultsDb: this.vaultsDb, - vaultsDbDomain: this.vaultsDbDomain, + vaultsDbPath: this.vaultsDbPath, keyManager: this.keyManager, efs: this.efs, logger: this.logger.getChild(VaultInternal.name), + tran, }); this.vaultMap.set(vaultIdString, { lock, vault }); - const vaultMetadata = (await this.getVaultMeta(vaultId))!; + const vaultMetadata = (await this.getVaultMeta(vaultId, tran))!; const baseVaultName = vaultMetadata.vaultName; // Need to check if the name is taken, 10 attempts let newVaultName = baseVaultName; let attempts = 1; while (true) { - const existingVaultId = await this.db.get( - this.vaultsNamesDbDomain, + const existingVaultId = await tran.get([ + ...this.vaultsNamesDbPath, newVaultName, - ); + ]); if (existingVaultId == null) break; newVaultName = `${baseVaultName}-${attempts}`; if (attempts >= 50) { @@ -596,16 +680,18 @@ class VaultManager { attempts++; } // Set the vaultName -> vaultId mapping - await this.db.put( - this.vaultsNamesDbDomain, - newVaultName, + await tran.put( + [...this.vaultsNamesDbPath, newVaultName], vaultId.toBuffer(), true, ); // Update vault metadata - await this.db.put( - [...this.vaultsDbDomain, vaultsUtils.encodeVaultId(vaultId)], - VaultInternal.nameKey, + await tran.put( + [ + ...this.vaultsDbPath, + vaultsUtils.encodeVaultId(vaultId), + VaultInternal.nameKey, + ], newVaultName, ); this.logger.info( @@ -623,18 +709,27 @@ class VaultManager { vaultId, pullNodeId, pullVaultNameOrId, + tran, }: { vaultId: VaultId; pullNodeId?: NodeId; pullVaultNameOrId?: VaultId | VaultName; + tran?: DBTransaction; }): Promise { - if ((await this.getVaultName(vaultId)) == null) return; + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.pullVault({ vaultId, pullNodeId, pullVaultNameOrId, tran }), + ); + } + + if ((await this.getVaultName(vaultId, tran)) == null) return; await withF([this.getWriteLock(vaultId)], async () => { - const vault = await this.getVault(vaultId); + const vault = await this.getVault(vaultId, tran); await vault.pullVault({ nodeConnectionManager: this.nodeConnectionManager, pullNodeId, pullVaultNameOrId, + tran, }); }); } @@ -644,11 +739,20 @@ class VaultManager { * cloned or pulled from */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - public async *handleInfoRequest(vaultId: VaultId): AsyncGenerator { + public async *handleInfoRequest( + vaultId: VaultId, + tran?: DBTransaction, + ): AsyncGenerator { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.handleInfoRequest(vaultId, tran), + ); + } + const efs = this.efs; - const vault = await this.getVault(vaultId); + const vault = await this.getVault(vaultId, tran); return yield* withG( - [this.getReadLock(vaultId), vault.readLock], + [this.getReadLock(vaultId), vault.getLock().read()], async function* (): AsyncGenerator { // Adherence to git protocol yield Buffer.from( @@ -677,10 +781,17 @@ class VaultManager { public async handlePackRequest( vaultId: VaultId, body: Buffer, + tran?: DBTransaction, ): Promise<[PassThrough, PassThrough]> { - const vault = await this.getVault(vaultId); + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.handlePackRequest(vaultId, body, tran), + ); + } + + const vault = await this.getVault(vaultId, tran); return await withF( - [this.getReadLock(vaultId), vault.readLock], + [this.getReadLock(vaultId), vault.getLock().read()], async () => { if (body.toString().slice(4, 8) === 'want') { // Parse the request to get the wanted git object @@ -744,14 +855,25 @@ class VaultManager { /** * Returns all the shared vaults for a NodeId. */ - public async *handleScanVaults(nodeId: NodeId): AsyncGenerator<{ + public async *handleScanVaults( + nodeId: NodeId, + tran?: DBTransaction, + ): AsyncGenerator<{ vaultId: VaultId; vaultName: VaultName; vaultPermissions: VaultAction[]; }> { + if (tran == null) { + // Lambda to maintain `this` context + const handleScanVaults = (tran) => this.handleScanVaults(nodeId, tran); + return yield* this.db.withTransactionG(async function* (tran) { + return yield* handleScanVaults(tran); + }); + } + // Checking permission const nodeIdEncoded = nodesUtils.encodeNodeId(nodeId); - const permissions = await this.acl.getNodePerm(nodeId); + const permissions = await this.acl.getNodePerm(nodeId, tran); if (permissions == null) { throw new vaultsErrors.ErrorVaultsPermissionDenied( `No permissions found for ${nodeIdEncoded}`, @@ -772,7 +894,7 @@ class VaultManager { vaults[vaultIdString], ) as VaultAction[]; // Getting the vault name - const metadata = await this.getVaultMeta(vaultId); + const metadata = await this.getVaultMeta(vaultId, tran); const vaultName = metadata!.vaultName; const element = { vaultId, @@ -800,9 +922,18 @@ class VaultManager { } @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) - protected async getVault(vaultId: VaultId): Promise { + protected async getVault( + vaultId: VaultId, + tran: DBTransaction, + ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.getVault(vaultId, tran), + ); + } + let vault: VaultInternal | undefined; - let lock: RWLock; + let lock: RWLockWriter; const vaultIdString = vaultId.toString() as VaultIdString; let vaultAndLock = this.vaultMap.get(vaultIdString); if (vaultAndLock != null) { @@ -812,15 +943,15 @@ class VaultManager { return vault; } // Only lock exists - let release; + let release: ResourceRelease | undefined; try { - release = await lock.acquireWrite(); + [release] = await lock.write()(); ({ vault } = vaultAndLock); if (vault != null) { return vault; } // Only create if the vault state already exists - if ((await this.getVaultMeta(vaultId)) == null) { + if ((await this.getVaultMeta(vaultId, tran)) == null) { throw new vaultsErrors.ErrorVaultsVaultUndefined( `Vault ${vaultsUtils.encodeVaultId(vaultId)} doesn't exist`, ); @@ -831,25 +962,25 @@ class VaultManager { efs: this.efs, logger: this.logger.getChild(VaultInternal.name), db: this.db, - vaultsDb: this.vaultsDb, - vaultsDbDomain: this.vaultsDbDomain, + vaultsDbPath: this.vaultsDbPath, + tran, }); vaultAndLock.vault = vault; this.vaultMap.set(vaultIdString, vaultAndLock); return vault; } finally { - release(); + if (release != null) await release(); } } else { // Neither vault nor lock exists - lock = new RWLock(); + lock = new RWLockWriter(); vaultAndLock = { lock }; this.vaultMap.set(vaultIdString, vaultAndLock); - let release; + let release: ResourceRelease | undefined; try { - release = await lock.acquireWrite(); + [release] = await lock.write()(); // Only create if the vault state already exists - if ((await this.getVaultMeta(vaultId)) == null) { + if ((await this.getVaultMeta(vaultId, tran)) == null) { throw new vaultsErrors.ErrorVaultsVaultUndefined( `Vault ${vaultsUtils.encodeVaultId(vaultId)} doesn't exist`, ); @@ -859,15 +990,15 @@ class VaultManager { keyManager: this.keyManager, efs: this.efs, db: this.db, - vaultsDb: this.vaultsDb, - vaultsDbDomain: this.vaultsDbDomain, + vaultsDbPath: this.vaultsDbPath, logger: this.logger.getChild(VaultInternal.name), + tran, }); vaultAndLock.vault = vault; this.vaultMap.set(vaultIdString, vaultAndLock); return vault; } finally { - release(); + if (release != null) await release(); } } } @@ -878,12 +1009,20 @@ class VaultManager { * Takes a function and runs it with the listed vaults. locking is handled automatically * @param vaultIds List of vault ID for vaults you wish to use * @param f Function you wish to run with the provided vaults + * @param tran */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) public async withVaults( vaultIds: VaultId[], f: (...args: Vault[]) => Promise, + tran?: DBTransaction, ): Promise { + if (tran == null) { + return this.db.withTransactionF(async (tran) => + this.withVaults(vaultIds, f, tran), + ); + } + // Stages: // 1. Obtain vaults // 2. Call function with vaults while locking the vaults @@ -892,7 +1031,7 @@ class VaultManager { const vaults = await Promise.all( vaultIds.map(async (vaultId) => { - return await this.getVault(vaultId); + return await this.getVault(vaultId, tran); }), ); @@ -907,9 +1046,12 @@ class VaultManager { }); } - protected async setupKey(bits: 128 | 192 | 256): Promise { + protected async setupKey( + bits: 128 | 192 | 256, + tran: DBTransaction, + ): Promise { let key: Buffer | undefined; - key = await this.db.get(this.vaultsDbDomain, 'key', true); + key = await tran.get([...this.vaultsDbPath, 'key'], true); // If the EFS already exists, but the key doesn't, then we have lost the key if (key == null && (await this.existsEFS())) { throw new vaultsErrors.ErrorVaultManagerKey(); @@ -919,7 +1061,7 @@ class VaultManager { } this.logger.info('Generating vaults key'); key = await this.generateKey(bits); - await this.db.put(this.vaultsDbDomain, 'key', key, true); + await tran.put([...this.vaultsDbPath, 'key'], key, true); return key; } @@ -935,10 +1077,13 @@ class VaultManager { return false; } throw new vaultsErrors.ErrorVaultManagerEFS(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, + data: { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }, + cause: e, }); } } diff --git a/src/vaults/VaultOps.ts b/src/vaults/VaultOps.ts index 203bb4a4a..3de1edd1c 100644 --- a/src/vaults/VaultOps.ts +++ b/src/vaults/VaultOps.ts @@ -109,6 +109,7 @@ async function getSecret(vault: Vault, secretName: string): Promise { if (err.code === 'ENOENT') { throw new vaultsErrors.ErrorSecretsSecretUndefined( `Secret with name: ${secretName} does not exist`, + { cause: err }, ); } throw err; @@ -124,6 +125,7 @@ async function statSecret(vault: Vault, secretName: string): Promise { if (err.code === 'ENOENT') { throw new vaultsErrors.ErrorSecretsSecretUndefined( `Secret with name: ${secretName} does not exist`, + { cause: err }, ); } throw err; @@ -178,6 +180,7 @@ async function mkdir( if (err.code === 'ENOENT' && !recursive) { throw new vaultsErrors.ErrorVaultsRecursive( `Could not create directory '${dirPath}' without recursive option`, + { cause: err }, ); } } diff --git a/src/vaults/errors.ts b/src/vaults/errors.ts index 43e877caf..f8db78e31 100644 --- a/src/vaults/errors.ts +++ b/src/vaults/errors.ts @@ -1,113 +1,114 @@ import { ErrorPolykey, sysexits } from '../errors'; -class ErrorVaults extends ErrorPolykey {} +class ErrorVaults extends ErrorPolykey {} -class ErrorVaultManagerRunning extends ErrorVaults { - description = 'VaultManager is running'; +class ErrorVaultManagerRunning extends ErrorVaults { + static description = 'VaultManager is running'; exitCode = sysexits.USAGE; } -class ErrorVaultManagerNotRunning extends ErrorVaults { - description = 'VaultManager is not running'; +class ErrorVaultManagerNotRunning extends ErrorVaults { + static description = 'VaultManager is not running'; exitCode = sysexits.USAGE; } -class ErrorVaultManagerDestroyed extends ErrorVaults { - description = 'VaultManager is destroyed'; +class ErrorVaultManagerDestroyed extends ErrorVaults { + static description = 'VaultManager is destroyed'; exitCode = sysexits.USAGE; } -class ErrorVaultManagerKey extends ErrorVaults { - description = 'Vault key is invalid'; +class ErrorVaultManagerKey extends ErrorVaults { + static description = 'Vault key is invalid'; exitCode = sysexits.CONFIG; } -class ErrorVaultManagerEFS extends ErrorVaults { - description = 'EFS failed'; +class ErrorVaultManagerEFS extends ErrorVaults { + static description = 'EFS failed'; exitCode = sysexits.UNAVAILABLE; } -class ErrorVault extends ErrorVaults {} +class ErrorVault extends ErrorVaults {} -class ErrorVaultRunning extends ErrorVault { - description = 'Vault is running'; +class ErrorVaultRunning extends ErrorVault { + static description = 'Vault is running'; exitCode = sysexits.USAGE; } -class ErrorVaultNotRunning extends ErrorVault { - description = 'Vault is not running'; +class ErrorVaultNotRunning extends ErrorVault { + static description = 'Vault is not running'; exitCode = sysexits.USAGE; } -class ErrorVaultDestroyed extends ErrorVault { - description = 'Vault is destroyed'; +class ErrorVaultDestroyed extends ErrorVault { + static description = 'Vault is destroyed'; exitCode = sysexits.USAGE; } -class ErrorVaultReferenceInvalid extends ErrorVault { - description = 'Reference is invalid'; +class ErrorVaultReferenceInvalid extends ErrorVault { + static description = 'Reference is invalid'; exitCode = sysexits.USAGE; } -class ErrorVaultReferenceMissing extends ErrorVault { - description = 'Reference does not exist'; +class ErrorVaultReferenceMissing extends ErrorVault { + static description = 'Reference does not exist'; exitCode = sysexits.USAGE; } -class ErrorVaultRemoteDefined extends ErrorVaults { - description = 'Vault is a clone of a remote vault and can not be mutated'; +class ErrorVaultRemoteDefined extends ErrorVaults { + static description = + 'Vault is a clone of a remote vault and can not be mutated'; exitCode = sysexits.USAGE; } -class ErrorVaultRemoteUndefined extends ErrorVaults { - description = 'Vault has no remote set and can not be pulled'; +class ErrorVaultRemoteUndefined extends ErrorVaults { + static description = 'Vault has no remote set and can not be pulled'; exitCode = sysexits.USAGE; } -class ErrorVaultsVaultUndefined extends ErrorVaults { - description = 'Vault does not exist'; +class ErrorVaultsVaultUndefined extends ErrorVaults { + static description = 'Vault does not exist'; exitCode = sysexits.USAGE; } -class ErrorVaultsVaultDefined extends ErrorVaults { - description = 'Vault already exists'; +class ErrorVaultsVaultDefined extends ErrorVaults { + static description = 'Vault already exists'; exitCode = sysexits.USAGE; } -class ErrorVaultsRecursive extends ErrorVaults { - description = 'Recursive option was not set'; +class ErrorVaultsRecursive extends ErrorVaults { + static description = 'Recursive option was not set'; exitCode = sysexits.USAGE; } -class ErrorVaultsCreateVaultId extends ErrorVaults { - description = 'Failed to create unique VaultId'; +class ErrorVaultsCreateVaultId extends ErrorVaults { + static description = 'Failed to create unique VaultId'; exitCode = sysexits.SOFTWARE; } -class ErrorVaultsMergeConflict extends ErrorVaults { - description = 'Merge Conflicts are not supported yet'; +class ErrorVaultsMergeConflict extends ErrorVaults { + static description = 'Merge Conflicts are not supported yet'; exitCode = sysexits.SOFTWARE; } -class ErrorVaultsPermissionDenied extends ErrorVaults { - description = 'Permission was denied'; +class ErrorVaultsPermissionDenied extends ErrorVaults { + static description = 'Permission was denied'; exitCode = sysexits.NOPERM; } -class ErrorVaultsNameConflict extends ErrorVaults { - description = 'Unique name could not be created'; +class ErrorVaultsNameConflict extends ErrorVaults { + static description = 'Unique name could not be created'; exitCode = sysexits.UNAVAILABLE; } -class ErrorSecrets extends ErrorPolykey {} +class ErrorSecrets extends ErrorPolykey {} -class ErrorSecretsSecretUndefined extends ErrorSecrets { - description = 'Secret does not exist'; +class ErrorSecretsSecretUndefined extends ErrorSecrets { + static description = 'Secret does not exist'; exitCode = sysexits.USAGE; } -class ErrorSecretsSecretDefined extends ErrorSecrets { - description = 'Secret already exists'; +class ErrorSecretsSecretDefined extends ErrorSecrets { + static description = 'Secret already exists'; exitCode = sysexits.USAGE; } diff --git a/tests/acl/ACL.test.ts b/tests/acl/ACL.test.ts index a75819f2f..a671caf10 100644 --- a/tests/acl/ACL.test.ts +++ b/tests/acl/ACL.test.ts @@ -7,9 +7,10 @@ import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { DB } from '@matrixai/db'; -import { ACL, errors as aclErrors } from '@/acl'; -import { utils as keysUtils } from '@/keys'; -import { utils as vaultsUtils } from '@/vaults'; +import ACL from '@/acl/ACL'; +import * as aclErrors from '@/acl/errors'; +import * as keysUtils from '@/keys/utils'; +import * as vaultsUtils from '@/vaults/utils'; import * as testUtils from '../utils'; describe(ACL.name, () => { @@ -107,30 +108,18 @@ describe(ACL.name, () => { await expect(acl.setNodesPerm([], {} as Permission)).rejects.toThrow( aclErrors.ErrorACLNotRunning, ); - await expect(acl.setNodesPermOps([], {} as Permission)).rejects.toThrow( - aclErrors.ErrorACLNotRunning, - ); await expect(acl.setNodePerm(nodeIdX, {} as Permission)).rejects.toThrow( aclErrors.ErrorACLNotRunning, ); - await expect(acl.setNodePermOps(nodeIdX, {} as Permission)).rejects.toThrow( - aclErrors.ErrorACLNotRunning, - ); await expect(acl.unsetNodePerm(nodeIdX)).rejects.toThrow( aclErrors.ErrorACLNotRunning, ); - await expect(acl.unsetNodePermOps(nodeIdX)).rejects.toThrow( - aclErrors.ErrorACLNotRunning, - ); await expect(acl.unsetVaultPerms(1 as VaultId)).rejects.toThrow( aclErrors.ErrorACLNotRunning, ); await expect(acl.joinNodePerm(nodeIdX, [])).rejects.toThrow( aclErrors.ErrorACLNotRunning, ); - await expect(acl.joinNodePermOps(nodeIdX, [])).rejects.toThrow( - aclErrors.ErrorACLNotRunning, - ); await expect(acl.joinVaultPerms(1 as VaultId, [])).rejects.toThrow( aclErrors.ErrorACLNotRunning, ); @@ -417,35 +406,45 @@ describe(ACL.name, () => { test('transactional operations', async () => { const acl = await ACL.createACL({ db, logger }); const p1 = acl.getNodePerms(); - const p2 = acl.transaction(async (acl) => { - await acl.setNodesPerm([nodeIdG1First, nodeIdG1Second] as Array, { - gestalt: { - notify: null, + const p2 = acl.withTransactionF(async (tran) => { + await acl.setNodesPerm( + [nodeIdG1First, nodeIdG1Second] as Array, + { + gestalt: { + notify: null, + }, + vaults: {}, }, - vaults: {}, - }); - await acl.setNodesPerm([nodeIdG2First, nodeIdG2Second] as Array, { - gestalt: { - notify: null, + tran, + ); + await acl.setNodesPerm( + [nodeIdG2First, nodeIdG2Second] as Array, + { + gestalt: { + notify: null, + }, + vaults: {}, }, - vaults: {}, - }); - await acl.setVaultAction(vaultId1, nodeIdG1First, 'pull'); - await acl.setVaultAction(vaultId1, nodeIdG2First, 'clone'); - await acl.joinNodePerm(nodeIdG1Second, [ - nodeIdG1Third, - nodeIdG1Fourth, - ] as Array); + tran, + ); + await acl.setVaultAction(vaultId1, nodeIdG1First, 'pull', tran); + await acl.setVaultAction(vaultId1, nodeIdG2First, 'clone', tran); + await acl.joinNodePerm( + nodeIdG1Second, + [nodeIdG1Third, nodeIdG1Fourth] as Array, + undefined, + tran, + ); // V3 and v4 joins v1 // this means v3 and v4 now has g1 and g2 permissions - await acl.joinVaultPerms(vaultId1, [vaultId3, vaultId4]); + await acl.joinVaultPerms(vaultId1, [vaultId3, vaultId4], tran); // Removing v3 - await acl.unsetVaultPerms(vaultId3); + await acl.unsetVaultPerms(vaultId3, tran); // Removing g1-second - await acl.unsetNodePerm(nodeIdG1Second); + await acl.unsetNodePerm(nodeIdG1Second, tran); // Unsetting pull just for v1 for g1 - await acl.unsetVaultAction(vaultId1, nodeIdG1First, 'pull'); - return await acl.getNodePerms(); + await acl.unsetVaultAction(vaultId1, nodeIdG1First, 'pull', tran); + return await acl.getNodePerms(tran); }); const p3 = acl.getNodePerms(); const results = await Promise.all([p1, p2, p3]); diff --git a/tests/agent/GRPCClientAgent.test.ts b/tests/agent/GRPCClientAgent.test.ts index 78808e361..60a84410c 100644 --- a/tests/agent/GRPCClientAgent.test.ts +++ b/tests/agent/GRPCClientAgent.test.ts @@ -156,6 +156,8 @@ describe(GRPCClientAgent.name, () => { acl, gestaltGraph, proxy, + db, + logger, }); client = await testAgentUtils.openTestAgentClient(port); await proxy.start({ diff --git a/tests/agent/service/nodesCrossSignClaim.test.ts b/tests/agent/service/nodesCrossSignClaim.test.ts index 0c3a1da7a..bc676db86 100644 --- a/tests/agent/service/nodesCrossSignClaim.test.ts +++ b/tests/agent/service/nodesCrossSignClaim.test.ts @@ -5,6 +5,7 @@ import fs from 'fs'; import path from 'path'; import os from 'os'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +import { ErrorPolykeyRemote } from '@/errors'; import PolykeyAgent from '@/PolykeyAgent'; import GRPCServer from '@/grpc/GRPCServer'; import GRPCClientAgent from '@/agent/GRPCClientAgent'; @@ -14,7 +15,6 @@ import * as nodesPB from '@/proto/js/polykey/v1/nodes/nodes_pb'; import * as keysUtils from '@/keys/utils'; import * as nodesUtils from '@/nodes/utils'; import * as claimsUtils from '@/claims/utils'; -import * as claimsErrors from '@/claims/errors'; import * as testNodesUtils from '../../nodes/utils'; import * as testUtils from '../../utils'; @@ -22,7 +22,7 @@ describe('nodesCrossSignClaim', () => { const logger = new Logger('nodesCrossSignClaim test', LogLevel.WARN, [ new StreamHandler(), ]); - const password = 'helloworld'; + const password = 'hello-world'; let dataDir: string; let nodePath: string; let grpcServer: GRPCServer; @@ -78,6 +78,8 @@ describe('nodesCrossSignClaim', () => { keyManager: pkAgent.keyManager, nodeManager: pkAgent.nodeManager, sigchain: pkAgent.sigchain, + db: pkAgent.db, + logger, }), }; grpcServer = new GRPCServer({ logger }); @@ -136,7 +138,6 @@ describe('nodesCrossSignClaim', () => { // 2. Singly signed intermediary claim const response = await genClaims.read(); // Check X's sigchain is locked at start - expect(pkAgent.sigchain.locked).toBe(true); expect(response.done).toBe(false); expect(response.value).toBeInstanceOf(nodesPB.CrossSign); const receivedMessage = response.value as nodesPB.CrossSign; @@ -175,14 +176,12 @@ describe('nodesCrossSignClaim', () => { doublySignedClaim: doublyResponse, }); // Just before we complete the last step, check X's sigchain is still locked - expect(pkAgent.sigchain.locked).toBe(true); await genClaims.write(doublyMessage); // Expect the stream to be closed. const finalResponse = await genClaims.read(); expect(finalResponse.done).toBe(true); expect(genClaims.stream.destroyed).toBe(true); // Check X's sigchain is released at end. - expect(pkAgent.sigchain.locked).toBe(false); // Check claim is in both node's sigchains // Rather, check it's in X's sigchain const chain = await pkAgent.sigchain.getChainData(); @@ -204,12 +203,9 @@ describe('nodesCrossSignClaim', () => { // 2. X <- sends its intermediary signed claim <- Y const crossSignMessageUndefinedSingly = new nodesPB.CrossSign(); await genClaims.write(crossSignMessageUndefinedSingly); - await expect(() => genClaims.read()).rejects.toThrow( - claimsErrors.ErrorUndefinedSinglySignedClaim, - ); + await expect(() => genClaims.read()).rejects.toThrow(ErrorPolykeyRemote); expect(genClaims.stream.destroyed).toBe(true); // Check sigchain's lock is released - expect(pkAgent.sigchain.locked).toBe(false); // Revert side effects await pkAgent.sigchain.stop(); await pkAgent.sigchain.destroy(); @@ -226,12 +222,9 @@ describe('nodesCrossSignClaim', () => { intermediaryNoSignature, ); await genClaims.write(crossSignMessageUndefinedSinglySignature); - await expect(() => genClaims.read()).rejects.toThrow( - claimsErrors.ErrorUndefinedSignature, - ); + await expect(() => genClaims.read()).rejects.toThrow(ErrorPolykeyRemote); expect(genClaims.stream.destroyed).toBe(true); // Check sigchain's lock is released - expect(pkAgent.sigchain.locked).toBe(false); // Revert side effects await pkAgent.sigchain.stop(); await pkAgent.sigchain.destroy(); diff --git a/tests/agent/service/notificationsSend.test.ts b/tests/agent/service/notificationsSend.test.ts index a0eb81ffa..c0b79e91c 100644 --- a/tests/agent/service/notificationsSend.test.ts +++ b/tests/agent/service/notificationsSend.test.ts @@ -28,6 +28,7 @@ import * as keysUtils from '@/keys/utils'; import * as nodesUtils from '@/nodes/utils'; import * as notificationsUtils from '@/notifications/utils'; import * as testUtils from '../../utils'; +import { expectRemoteError } from '../../utils'; describe('notificationsSend', () => { const logger = new Logger('notificationsSend test', LogLevel.WARN, [ @@ -137,6 +138,8 @@ describe('notificationsSend', () => { const agentService = { notificationsSend: notificationsSend({ notificationsManager, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); @@ -221,9 +224,10 @@ describe('notificationsSend', () => { }; const request1 = new notificationsPB.AgentNotification(); request1.setContent(notification1.toString()); - await expect(async () => + await expectRemoteError( grpcClient.notificationsSend(request1), - ).rejects.toThrow(notificationsErrors.ErrorNotificationsParse); + notificationsErrors.ErrorNotificationsParse, + ); // Check notification was not received let receivedNotifications = await notificationsManager.readNotifications(); expect(receivedNotifications).toHaveLength(0); @@ -248,9 +252,10 @@ describe('notificationsSend', () => { .sign(privateKey); const request2 = new notificationsPB.AgentNotification(); request2.setContent(signedNotification); - await expect(async () => + await expectRemoteError( grpcClient.notificationsSend(request2), - ).rejects.toThrow(notificationsErrors.ErrorNotificationsValidationFailed); + notificationsErrors.ErrorNotificationsValidationFailed, + ); // Check notification was not received receivedNotifications = await notificationsManager.readNotifications(); expect(receivedNotifications).toHaveLength(0); @@ -273,9 +278,8 @@ describe('notificationsSend', () => { ); const request = new notificationsPB.AgentNotification(); request.setContent(signedNotification); - await expect(async () => + await expectRemoteError( grpcClient.notificationsSend(request), - ).rejects.toThrow( notificationsErrors.ErrorNotificationsPermissionsNotFound, ); // Check notification was not received diff --git a/tests/agent/utils.ts b/tests/agent/utils.ts index 8cf77303e..f2b896024 100644 --- a/tests/agent/utils.ts +++ b/tests/agent/utils.ts @@ -3,20 +3,22 @@ import type { Host, Port, ProxyConfig } from '@/network/types'; import type { IAgentServiceServer } from '@/proto/js/polykey/v1/agent_service_grpc_pb'; import type { KeyManager } from '@/keys'; import type { VaultManager } from '@/vaults'; -import type { NodeGraph, NodeConnectionManager, NodeManager } from '@/nodes'; +import type { NodeConnectionManager, NodeGraph, NodeManager } from '@/nodes'; import type { Sigchain } from '@/sigchain'; import type { NotificationsManager } from '@/notifications'; import type { ACL } from '@/acl'; import type { GestaltGraph } from '@/gestalts'; import type { NodeId } from 'nodes/types'; import type Proxy from 'network/Proxy'; +import type { DB } from '@matrixai/db'; +import type { Server } from '@grpc/grpc-js'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import { promisify } from '@/utils'; import { + AgentServiceService, createAgentService, GRPCClientAgent, - AgentServiceService, } from '@/agent'; import * as testUtils from '../utils'; @@ -31,6 +33,8 @@ async function openTestAgentServer({ acl, gestaltGraph, proxy, + db, + logger, }: { keyManager: KeyManager; vaultManager: VaultManager; @@ -42,7 +46,9 @@ async function openTestAgentServer({ acl: ACL; gestaltGraph: GestaltGraph; proxy: Proxy; -}) { + db: DB; + logger: Logger; +}): Promise<[Server, Port]> { const agentService: IAgentServiceServer = createAgentService({ keyManager, vaultManager, @@ -54,6 +60,8 @@ async function openTestAgentServer({ acl, gestaltGraph, proxy, + db, + logger, }); const server = new grpc.Server(); @@ -80,7 +88,7 @@ async function openTestAgentClient( const logger = new Logger('AgentClientTest', LogLevel.WARN, [ new StreamHandler(), ]); - const agentClient = await GRPCClientAgent.createGRPCClientAgent({ + return await GRPCClientAgent.createGRPCClientAgent({ nodeId: nodeId ?? testUtils.generateRandomNodeId(), host: '127.0.0.1' as Host, port: port as Port, @@ -89,7 +97,6 @@ async function openTestAgentClient( proxyConfig, timeout: 30000, }); - return agentClient; } async function closeTestAgentClient(client: GRPCClientAgent) { diff --git a/tests/bin/identities/claim.test.ts b/tests/bin/identities/claim.test.ts index de1817c30..f2e730b9c 100644 --- a/tests/bin/identities/claim.test.ts +++ b/tests/bin/identities/claim.test.ts @@ -125,7 +125,7 @@ describe('claim', () => { }, dataDir, ); - expect(exitCode).toBe(1); + expect(exitCode).toBe(sysexits.NOPERM); }); test('should fail on invalid inputs', async () => { let exitCode; diff --git a/tests/bin/identities/trustUntrustList.test.ts b/tests/bin/identities/trustUntrustList.test.ts index a11c13260..5fb91633d 100644 --- a/tests/bin/identities/trustUntrustList.test.ts +++ b/tests/bin/identities/trustUntrustList.test.ts @@ -1,14 +1,13 @@ import type { Host, Port } from '@/network/types'; import type { IdentityId, ProviderId } from '@/identities/types'; import type { ClaimLinkIdentity } from '@/claims/types'; -import type { Gestalt } from '@/gestalts/types'; import type { NodeId } from '@/nodes/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import PolykeyAgent from '@/PolykeyAgent'; -import { poll, sysexits } from '@/utils'; +import { sysexits } from '@/utils'; import * as nodesUtils from '@/nodes/utils'; import * as keysUtils from '@/keys/utils'; import * as claimsUtils from '@/claims/utils'; @@ -156,27 +155,7 @@ describe('trust/untrust/list', () => { expect(exitCode).toBe(0); // Since discovery is a background process we need to wait for the // gestalt to be discovered - await poll( - async () => { - const gestalts = await poll>( - async () => { - return await pkAgent.gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 2) return true; - return false; - }, - 100, - ); + await pkAgent.discovery.waitForDrained(); // Check that gestalt was discovered and permission was set ({ exitCode, stdout } = await testBinUtils.pkStdio( ['identities', 'list', '--format', 'json'], @@ -290,30 +269,10 @@ describe('trust/untrust/list', () => { }, dataDir, )); - expect(exitCode).toBe(1); + expect(exitCode).toBe(sysexits.NOUSER); // Since discovery is a background process we need to wait for the // gestalt to be discovered - await poll( - async () => { - const gestalts = await poll>( - async () => { - return await pkAgent.gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 2) return true; - return false; - }, - 100, - ); + await pkAgent.discovery.waitForDrained(); // This time the command should succeed ({ exitCode } = await testBinUtils.pkStdio( ['identities', 'trust', providerString], diff --git a/tests/bin/nodes/find.test.ts b/tests/bin/nodes/find.test.ts index 6be67177a..56bffd263 100644 --- a/tests/bin/nodes/find.test.ts +++ b/tests/bin/nodes/find.test.ts @@ -7,6 +7,7 @@ import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import PolykeyAgent from '@/PolykeyAgent'; import * as nodesUtils from '@/nodes/utils'; import * as keysUtils from '@/keys/utils'; +import { sysexits } from '@/errors'; import * as testBinUtils from '../utils'; import * as testNodesUtils from '../../nodes/utils'; import * as testUtils from '../../utils'; @@ -175,7 +176,7 @@ describe('find', () => { }, dataDir, ); - expect(exitCode).toBe(1); + expect(exitCode).toBe(sysexits.GENERAL); expect(JSON.parse(stdout)).toEqual({ success: false, message: `Failed to find node ${nodesUtils.encodeNodeId(unknownNodeId!)}`, diff --git a/tests/bin/nodes/ping.test.ts b/tests/bin/nodes/ping.test.ts index 196ec8ce8..f531a04d2 100644 --- a/tests/bin/nodes/ping.test.ts +++ b/tests/bin/nodes/ping.test.ts @@ -7,6 +7,7 @@ import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import PolykeyAgent from '@/PolykeyAgent'; import * as nodesUtils from '@/nodes/utils'; import * as keysUtils from '@/keys/utils'; +import { sysexits } from '@/errors'; import * as testBinUtils from '../utils'; import * as testNodesUtils from '../../nodes/utils'; import * as testUtils from '../../utils'; @@ -119,7 +120,7 @@ describe('ping', () => { }, dataDir, ); - expect(exitCode).toBe(1); // Should fail with no response. for automation purposes. + expect(exitCode).toBe(sysexits.GENERAL); // Should fail with no response. for automation purposes. expect(stderr).toContain('No response received'); expect(JSON.parse(stdout)).toEqual({ success: false, diff --git a/tests/bin/utils.ts b/tests/bin/utils.ts index 47211b018..3b552cf64 100644 --- a/tests/bin/utils.ts +++ b/tests/bin/utils.ts @@ -343,7 +343,7 @@ async function processExit( function expectProcessError( exitCode: number, stderr: string, - error: ErrorPolykey, + error: ErrorPolykey, ) { expect(exitCode).toBe(error.exitCode); const stdErrLine = stderr.trim().split('\n').pop(); diff --git a/tests/client/GRPCClientClient.test.ts b/tests/client/GRPCClientClient.test.ts index a6ce3f3bb..bb083f816 100644 --- a/tests/client/GRPCClientClient.test.ts +++ b/tests/client/GRPCClientClient.test.ts @@ -1,6 +1,6 @@ +import type * as grpc from '@grpc/grpc-js'; import type { Host, Port } from '@/network/types'; import type { NodeId } from '@/nodes/types'; -import type * as grpc from '@grpc/grpc-js'; import os from 'os'; import path from 'path'; import fs from 'fs'; diff --git a/tests/client/rpcVaults.test.ts b/tests/client/rpcVaults.test.ts index 6e477e62d..98f4b80af 100644 --- a/tests/client/rpcVaults.test.ts +++ b/tests/client/rpcVaults.test.ts @@ -3,22 +3,24 @@ import type VaultManager from '@/vaults/VaultManager'; import type { VaultId, VaultName } from '@/vaults/types'; import type { ClientServiceClient } from '@/proto/js/polykey/v1/client_service_grpc_pb'; import type { Stat } from 'encryptedfs'; +import type { Host, Port } from '@/network/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; -import { PolykeyAgent } from '@'; +import PolykeyAgent from '@/PolykeyAgent'; +import KeyManager from '@/keys/KeyManager'; +import Proxy from '@/network/Proxy'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; import * as secretsPB from '@/proto/js/polykey/v1/secrets/secrets_pb'; -import KeyManager from '@/keys/KeyManager'; -import Proxy from '@/network/Proxy'; import * as grpcUtils from '@/grpc/utils'; import * as vaultErrors from '@/vaults/errors'; import * as vaultsUtils from '@/vaults/utils'; import * as vaultOps from '@/vaults/VaultOps'; import * as nodesUtils from '@/nodes/utils'; import * as clientUtils from './utils'; +import { expectRemoteError } from '../utils'; jest.mock('@/keys/utils', () => ({ ...jest.requireActual('@/keys/utils'), @@ -38,6 +40,8 @@ describe('Vaults client service', () => { 'Vault4' as VaultName, ]; const secretList = ['Secret1', 'Secret2', 'Secret3', 'Secret4']; + const localHost = 'localhost' as Host; + const localPort = 55555 as Port; let client: ClientServiceClient; let server: grpc.Server; @@ -114,6 +118,8 @@ describe('Vaults client service', () => { test('should get vaults', async () => { const listVaults = grpcUtils.promisifyReadableStreamCall( client, + localHost, + localPort, client.vaultsList, ); for (const vaultName of vaultList) { @@ -247,7 +253,8 @@ describe('Vaults client service', () => { vaultVersionMessage.setVault(vaultMessage); vaultVersionMessage.setVersionId('invalidOid'); const version = vaultsVersion(vaultVersionMessage, callCredentials); - await expect(version).rejects.toThrow( + await expectRemoteError( + version, vaultErrors.ErrorVaultReferenceInvalid, ); @@ -255,7 +262,8 @@ describe('Vaults client service', () => { '7660aa9a2fee90e875c2d19e5deefe882ca1d4d9', ); const version2 = vaultsVersion(vaultVersionMessage, callCredentials); - await expect(version2).rejects.toThrow( + await expectRemoteError( + version2, vaultErrors.ErrorVaultReferenceMissing, ); }); diff --git a/tests/client/service/agentLockAll.test.ts b/tests/client/service/agentLockAll.test.ts index 21a533dd6..a024cc05c 100644 --- a/tests/client/service/agentLockAll.test.ts +++ b/tests/client/service/agentLockAll.test.ts @@ -75,6 +75,8 @@ describe('agentLockall', () => { agentLockAll: agentLockAll({ authenticate, sessionManager, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); @@ -87,6 +89,7 @@ describe('agentLockall', () => { nodeId: keyManager.getNodeId(), host: '127.0.0.1' as Host, port: grpcServer.getPort(), + timeout: 5000, logger, }); }); diff --git a/tests/client/service/agentStatus.test.ts b/tests/client/service/agentStatus.test.ts index 04c68aa2e..cb26d32d2 100644 --- a/tests/client/service/agentStatus.test.ts +++ b/tests/client/service/agentStatus.test.ts @@ -83,6 +83,7 @@ describe('agentStatus', () => { grpcServerClient, grpcServerAgent, proxy, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/agentStop.test.ts b/tests/client/service/agentStop.test.ts index 6a5e00dd4..a799729cb 100644 --- a/tests/client/service/agentStop.test.ts +++ b/tests/client/service/agentStop.test.ts @@ -59,6 +59,7 @@ describe('agentStop', () => { agentStop: agentStop({ authenticate, pkAgent: pkAgent as unknown as PolykeyAgent, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/agentUnlock.test.ts b/tests/client/service/agentUnlock.test.ts index 4ca05aba0..4a64076ad 100644 --- a/tests/client/service/agentUnlock.test.ts +++ b/tests/client/service/agentUnlock.test.ts @@ -22,6 +22,7 @@ describe('agentUnlock', () => { const clientService = { agentUnlock: agentUnlock({ authenticate, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts b/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts index 4ea77f742..381ec9b60 100644 --- a/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts +++ b/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts @@ -72,14 +72,20 @@ describe('gestaltsActionsByIdentity', () => { gestaltsActionsSetByIdentity: gestaltsActionsSetByIdentity({ authenticate, gestaltGraph, + logger, + db, }), gestaltsActionsGetByIdentity: gestaltsActionsGetByIdentity({ authenticate, gestaltGraph, + logger, + db, }), gestaltsActionsUnsetByIdentity: gestaltsActionsUnsetByIdentity({ authenticate, gestaltGraph, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts b/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts index 5eb2e40bf..439f9b754 100644 --- a/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts +++ b/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts @@ -66,14 +66,20 @@ describe('gestaltsActionsByNode', () => { gestaltsActionsSetByNode: gestaltsActionsSetByNode({ authenticate, gestaltGraph, + logger, + db, }), gestaltsActionsGetByNode: gestaltsActionsGetByNode({ authenticate, gestaltGraph, + logger, + db, }), gestaltsActionsUnsetByNode: gestaltsActionsUnsetByNode({ authenticate, gestaltGraph, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsDiscoveryByIdentity.test.ts b/tests/client/service/gestaltsDiscoveryByIdentity.test.ts index a987f6aad..2c314711b 100644 --- a/tests/client/service/gestaltsDiscoveryByIdentity.test.ts +++ b/tests/client/service/gestaltsDiscoveryByIdentity.test.ts @@ -155,6 +155,7 @@ describe('gestaltsDiscoveryByIdentity', () => { gestaltsDiscoveryByIdentity: gestaltsDiscoveryByIdentity({ authenticate, discovery, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsDiscoveryByNode.test.ts b/tests/client/service/gestaltsDiscoveryByNode.test.ts index d03fe307a..7071428e6 100644 --- a/tests/client/service/gestaltsDiscoveryByNode.test.ts +++ b/tests/client/service/gestaltsDiscoveryByNode.test.ts @@ -155,6 +155,7 @@ describe('gestaltsDiscoveryByNode', () => { gestaltsDiscoveryByNode: gestaltsDiscoveryByNode({ authenticate, discovery, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltGetByIdentity.test.ts b/tests/client/service/gestaltsGestaltGetByIdentity.test.ts index a8aa0b5bf..b6ecc2d71 100644 --- a/tests/client/service/gestaltsGestaltGetByIdentity.test.ts +++ b/tests/client/service/gestaltsGestaltGetByIdentity.test.ts @@ -89,6 +89,8 @@ describe('gestaltsGestaltGetByIdentity', () => { gestaltsGestaltGetByIdentity: gestaltsGestaltGetByIdentity({ authenticate, gestaltGraph, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltGetByNode.test.ts b/tests/client/service/gestaltsGestaltGetByNode.test.ts index ebff5bf7d..1d7a3ceb6 100644 --- a/tests/client/service/gestaltsGestaltGetByNode.test.ts +++ b/tests/client/service/gestaltsGestaltGetByNode.test.ts @@ -86,6 +86,8 @@ describe('gestaltsGestaltGetByNode', () => { gestaltsGestaltGetByNode: gestaltsGestaltGetByNode({ authenticate, gestaltGraph, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltList.test.ts b/tests/client/service/gestaltsGestaltList.test.ts index 6b714e073..1075a34f8 100644 --- a/tests/client/service/gestaltsGestaltList.test.ts +++ b/tests/client/service/gestaltsGestaltList.test.ts @@ -92,6 +92,8 @@ describe('gestaltsGestaltList', () => { gestaltsGestaltList: gestaltsGestaltList({ authenticate, gestaltGraph, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts b/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts index 8bd0a749e..ec38cc41d 100644 --- a/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts +++ b/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts @@ -1,7 +1,6 @@ import type { NodeIdEncoded } from '@/nodes/types'; import type { ClaimLinkIdentity } from '@/claims/types'; import type { ChainData } from '@/sigchain/types'; -import type { Gestalt } from '@/gestalts/types'; import type { IdentityId } from '@/identities/types'; import type { Host, Port } from '@/network/types'; import fs from 'fs'; @@ -25,7 +24,6 @@ import GRPCServer from '@/grpc/GRPCServer'; import GRPCClientClient from '@/client/GRPCClientClient'; import gestaltsGestaltTrustByIdentity from '@/client/service/gestaltsGestaltTrustByIdentity'; import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; -import { poll } from '@/utils'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import * as identitiesPB from '@/proto/js/polykey/v1/identities/identities_pb'; import * as claimsUtils from '@/claims/utils'; @@ -35,6 +33,7 @@ import * as clientUtils from '@/client/utils/utils'; import * as nodesUtils from '@/nodes/utils'; import * as testUtils from '../../utils'; import TestProvider from '../../identities/TestProvider'; +import { expectRemoteError } from '../../utils'; describe('gestaltsGestaltTrustByIdentity', () => { const logger = new Logger( @@ -227,6 +226,8 @@ describe('gestaltsGestaltTrustByIdentity', () => { authenticate, gestaltGraph, discovery, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); @@ -299,34 +300,15 @@ describe('gestaltsGestaltTrustByIdentity', () => { request.setIdentityId(connectedIdentity); // Should fail on first attempt - need to allow time for the identity to be // linked to a node via discovery - await expect( + await expectRemoteError( grpcClient.gestaltsGestaltTrustByIdentity( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing); - // Wait for both identity and node to be set in GG - await poll( - async () => { - const gestalts = await poll>( - async () => { - return await gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 2) return true; - return false; - }, - 100, + gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, ); + // Wait for both identity and node to be set in GG + await discovery.waitForDrained(); const response = await grpcClient.gestaltsGestaltTrustByIdentity( request, clientUtils.encodeAuthFromPassword(password), @@ -350,20 +332,22 @@ describe('gestaltsGestaltTrustByIdentity', () => { request.setProviderId(testProvider.id); request.setIdentityId('disconnected-user'); // Should fail on first attempt - attempt to find a connected node - await expect( + await expectRemoteError( grpcClient.gestaltsGestaltTrustByIdentity( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing); + gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, + ); // Wait and try again - should fail again because the identity has no // linked nodes we can trust - await expect( + await expectRemoteError( grpcClient.gestaltsGestaltTrustByIdentity( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing); + gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, + ); }); test('trust extends to entire gestalt', async () => { await gestaltGraph.linkNodeAndIdentity( @@ -414,35 +398,16 @@ describe('gestaltsGestaltTrustByIdentity', () => { request.setIdentityId(connectedIdentity); // Should fail on first attempt - need to allow time for the identity to be // linked to a node via discovery - await expect( + await expectRemoteError( grpcClient.gestaltsGestaltTrustByIdentity( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing); + gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, + ); // Wait and try again - should succeed second time // Wait for both identity and node to be set in GG - await poll( - async () => { - const gestalts = await poll>( - async () => { - return await gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 2) return true; - return false; - }, - 100, - ); + await discovery.waitForDrained(); const response = await grpcClient.gestaltsGestaltTrustByIdentity( request, clientUtils.encodeAuthFromPassword(password), diff --git a/tests/client/service/gestaltsGestaltTrustByNode.test.ts b/tests/client/service/gestaltsGestaltTrustByNode.test.ts index ccc7c827d..1c1ad87b0 100644 --- a/tests/client/service/gestaltsGestaltTrustByNode.test.ts +++ b/tests/client/service/gestaltsGestaltTrustByNode.test.ts @@ -225,6 +225,8 @@ describe('gestaltsGestaltTrustByNode', () => { authenticate, gestaltGraph, discovery, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/identitiesAuthenticate.test.ts b/tests/client/service/identitiesAuthenticate.test.ts index fb3c2a9ff..21b4f78dc 100644 --- a/tests/client/service/identitiesAuthenticate.test.ts +++ b/tests/client/service/identitiesAuthenticate.test.ts @@ -16,6 +16,7 @@ import * as validationErrors from '@/validation/errors'; import * as clientUtils from '@/client/utils/utils'; import * as nodesUtils from '@/nodes/utils'; import TestProvider from '../../identities/TestProvider'; +import { expectRemoteError } from '../../utils'; describe('identitiesAuthenticate', () => { const logger = new Logger('identitiesAuthenticate test', LogLevel.WARN, [ @@ -56,6 +57,7 @@ describe('identitiesAuthenticate', () => { identitiesAuthenticate: identitiesAuthenticate({ authenticate, identitiesManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); @@ -124,13 +126,14 @@ describe('identitiesAuthenticate', () => { test('cannot authenticate invalid provider', async () => { const request = new identitiesPB.Provider(); request.setProviderId(''); - await expect( + await expectRemoteError( grpcClient .identitiesAuthenticate( request, clientUtils.encodeAuthFromPassword(password), ) .next(), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); }); }); diff --git a/tests/client/service/identitiesAuthenticatedGet.test.ts b/tests/client/service/identitiesAuthenticatedGet.test.ts index 8233589d5..1dacdddbc 100644 --- a/tests/client/service/identitiesAuthenticatedGet.test.ts +++ b/tests/client/service/identitiesAuthenticatedGet.test.ts @@ -48,6 +48,7 @@ describe('identitiesAuthenticatedGet', () => { identitiesAuthenticatedGet: identitiesAuthenticatedGet({ authenticate, identitiesManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/identitiesClaim.test.ts b/tests/client/service/identitiesClaim.test.ts index b040a7b0a..39535394a 100644 --- a/tests/client/service/identitiesClaim.test.ts +++ b/tests/client/service/identitiesClaim.test.ts @@ -27,6 +27,7 @@ import * as nodesUtils from '@/nodes/utils'; import * as validationErrors from '@/validation/errors'; import * as testUtils from '../../utils'; import TestProvider from '../../identities/TestProvider'; +import { expectRemoteError } from '../../utils'; describe('identitiesClaim', () => { const logger = new Logger('identitiesClaim test', LogLevel.WARN, [ @@ -148,6 +149,8 @@ describe('identitiesClaim', () => { identitiesManager, sigchain, keyManager, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); @@ -207,27 +210,30 @@ describe('identitiesClaim', () => { const request = new identitiesPB.Provider(); request.setIdentityId(''); request.setProviderId(testToken.providerId); - await expect( + await expectRemoteError( grpcClient.identitiesClaim( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); request.setIdentityId(testToken.identityId); request.setProviderId(''); - await expect( + await expectRemoteError( grpcClient.identitiesClaim( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); request.setIdentityId(''); request.setProviderId(''); - await expect( + await expectRemoteError( grpcClient.identitiesClaim( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); }); }); diff --git a/tests/client/service/identitiesInfoConnectedGet.test.ts b/tests/client/service/identitiesInfoConnectedGet.test.ts index 0dce4a1bb..532690fe4 100644 --- a/tests/client/service/identitiesInfoConnectedGet.test.ts +++ b/tests/client/service/identitiesInfoConnectedGet.test.ts @@ -16,6 +16,7 @@ import * as clientUtils from '@/client/utils/utils'; import * as nodesUtils from '@/nodes/utils'; import * as identitiesErrors from '@/identities/errors'; import TestProvider from '../../identities/TestProvider'; +import { expectRemoteError } from '../../utils'; describe('identitiesInfoConnectedGet', () => { const logger = new Logger('identitiesInfoConnectedGet test', LogLevel.WARN, [ @@ -52,6 +53,7 @@ describe('identitiesInfoConnectedGet', () => { identitiesInfoConnectedGet: identitiesInfoConnectedGet({ authenticate, identitiesManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); @@ -728,13 +730,14 @@ describe('identitiesInfoConnectedGet', () => { // This feature is not implemented yet - should throw error const request = new identitiesPB.ProviderSearch(); request.setDisconnected(true); - await expect( + await expectRemoteError( grpcClient .identitiesInfoConnectedGet( request, clientUtils.encodeAuthFromPassword(password), ) .next(), - ).rejects.toThrow(identitiesErrors.ErrorProviderUnimplemented); + identitiesErrors.ErrorProviderUnimplemented, + ); }); }); diff --git a/tests/client/service/identitiesInfoGet.test.ts b/tests/client/service/identitiesInfoGet.test.ts index 41bc2a1e0..68b9df655 100644 --- a/tests/client/service/identitiesInfoGet.test.ts +++ b/tests/client/service/identitiesInfoGet.test.ts @@ -51,6 +51,7 @@ describe('identitiesInfoGet', () => { identitiesInfoGet: identitiesInfoGet({ authenticate, identitiesManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/identitiesProvidersList.test.ts b/tests/client/service/identitiesProvidersList.test.ts index 071703386..e75ffd477 100644 --- a/tests/client/service/identitiesProvidersList.test.ts +++ b/tests/client/service/identitiesProvidersList.test.ts @@ -60,6 +60,7 @@ describe('identitiesProvidersList', () => { identitiesProvidersList: identitiesProvidersList({ authenticate, identitiesManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/identitiesTokenPutDeleteGet.test.ts b/tests/client/service/identitiesTokenPutDeleteGet.test.ts index 6fca93e68..1752e2f94 100644 --- a/tests/client/service/identitiesTokenPutDeleteGet.test.ts +++ b/tests/client/service/identitiesTokenPutDeleteGet.test.ts @@ -56,14 +56,20 @@ describe('identitiesTokenPutDeleteGet', () => { identitiesTokenPut: identitiesTokenPut({ authenticate, identitiesManager, + logger, + db, }), identitiesTokenGet: identitiesTokenGet({ authenticate, identitiesManager, + logger, + db, }), identitiesTokenDelete: identitiesTokenDelete({ authenticate, identitiesManager, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/keysCertsChainGet.test.ts b/tests/client/service/keysCertsChainGet.test.ts index f0b97a681..48b734c95 100644 --- a/tests/client/service/keysCertsChainGet.test.ts +++ b/tests/client/service/keysCertsChainGet.test.ts @@ -61,6 +61,7 @@ describe('keysCertsChainGet', () => { keysCertsChainGet: keysCertsChainGet({ authenticate, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/keysCertsGet.test.ts b/tests/client/service/keysCertsGet.test.ts index ad2fb28ba..d3bd83e09 100644 --- a/tests/client/service/keysCertsGet.test.ts +++ b/tests/client/service/keysCertsGet.test.ts @@ -60,6 +60,7 @@ describe('keysCertsGet', () => { keysCertsGet: keysCertsGet({ authenticate, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/keysEncryptDecrypt.test.ts b/tests/client/service/keysEncryptDecrypt.test.ts index 0c2a1259a..a6421649f 100644 --- a/tests/client/service/keysEncryptDecrypt.test.ts +++ b/tests/client/service/keysEncryptDecrypt.test.ts @@ -55,10 +55,12 @@ describe('keysEncryptDecrypt', () => { keysEncrypt: keysEncrypt({ authenticate, keyManager, + logger, }), keysDecrypt: keysDecrypt({ authenticate, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/keysKeyPairRenew.test.ts b/tests/client/service/keysKeyPairRenew.test.ts index 714055cf0..8a792254b 100644 --- a/tests/client/service/keysKeyPairRenew.test.ts +++ b/tests/client/service/keysKeyPairRenew.test.ts @@ -74,6 +74,7 @@ describe('keysKeyPairRenew', () => { keysKeyPairRenew: keysKeyPairRenew({ authenticate, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); @@ -110,7 +111,7 @@ describe('keysKeyPairRenew', () => { certChainPem: await keyManager.getRootCertChainPem(), }; const nodeIdStatus1 = (await status.readStatus())!.data.nodeId; - expect(mockedRefreshBuckets.mock.calls).toHaveLength(0); + expect(mockedRefreshBuckets).toHaveBeenCalledTimes(0); expect(fwdTLSConfig1).toEqual(expectedTLSConfig1); expect(serverTLSConfig1).toEqual(expectedTLSConfig1); expect(nodeId1.equals(nodeIdStatus1)).toBe(true); @@ -133,7 +134,7 @@ describe('keysKeyPairRenew', () => { certChainPem: await keyManager.getRootCertChainPem(), }; const nodeIdStatus2 = (await status.readStatus())!.data.nodeId; - expect(mockedRefreshBuckets.mock.calls).toHaveLength(1); + expect(mockedRefreshBuckets).toHaveBeenCalled(); expect(fwdTLSConfig2).toEqual(expectedTLSConfig2); expect(serverTLSConfig2).toEqual(expectedTLSConfig2); expect(rootKeyPair2.privateKey).not.toBe(rootKeyPair1.privateKey); diff --git a/tests/client/service/keysKeyPairReset.test.ts b/tests/client/service/keysKeyPairReset.test.ts index 155d6071e..8c41064b1 100644 --- a/tests/client/service/keysKeyPairReset.test.ts +++ b/tests/client/service/keysKeyPairReset.test.ts @@ -74,6 +74,7 @@ describe('keysKeyPairReset', () => { keysKeyPairReset: keysKeyPairReset({ authenticate, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); @@ -110,7 +111,7 @@ describe('keysKeyPairReset', () => { certChainPem: await keyManager.getRootCertChainPem(), }; const nodeIdStatus1 = (await status.readStatus())!.data.nodeId; - expect(mockedRefreshBuckets.mock.calls).toHaveLength(0); + expect(mockedRefreshBuckets).not.toHaveBeenCalled(); expect(fwdTLSConfig1).toEqual(expectedTLSConfig1); expect(serverTLSConfig1).toEqual(expectedTLSConfig1); expect(nodeId1.equals(nodeIdStatus1)).toBe(true); @@ -133,7 +134,7 @@ describe('keysKeyPairReset', () => { certChainPem: await keyManager.getRootCertChainPem(), }; const nodeIdStatus2 = (await status.readStatus())!.data.nodeId; - expect(mockedRefreshBuckets.mock.calls).toHaveLength(1); + expect(mockedRefreshBuckets).toHaveBeenCalled(); expect(fwdTLSConfig2).toEqual(expectedTLSConfig2); expect(serverTLSConfig2).toEqual(expectedTLSConfig2); expect(rootKeyPair2.privateKey).not.toBe(rootKeyPair1.privateKey); diff --git a/tests/client/service/keysKeyPairRoot.test.ts b/tests/client/service/keysKeyPairRoot.test.ts index 19330b0cc..e5d5f2629 100644 --- a/tests/client/service/keysKeyPairRoot.test.ts +++ b/tests/client/service/keysKeyPairRoot.test.ts @@ -56,6 +56,7 @@ describe('keysKeyPairRoot', () => { keysKeyPairRoot: keysKeyPairRoot({ authenticate, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/keysPasswordChange.test.ts b/tests/client/service/keysPasswordChange.test.ts index 8f22e95e2..7814ec86a 100644 --- a/tests/client/service/keysPasswordChange.test.ts +++ b/tests/client/service/keysPasswordChange.test.ts @@ -62,6 +62,7 @@ describe('keysPasswordChange', () => { keysPasswordChange: keysPasswordChange({ authenticate, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/keysSignVerify.test.ts b/tests/client/service/keysSignVerify.test.ts index 34cf424fd..c420d7ed6 100644 --- a/tests/client/service/keysSignVerify.test.ts +++ b/tests/client/service/keysSignVerify.test.ts @@ -56,10 +56,12 @@ describe('keysSignVerify', () => { keysSign: keysSign({ authenticate, keyManager, + logger, }), keysVerify: keysVerify({ authenticate, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/nodesAdd.test.ts b/tests/client/service/nodesAdd.test.ts index 1cd51eb05..86923b961 100644 --- a/tests/client/service/nodesAdd.test.ts +++ b/tests/client/service/nodesAdd.test.ts @@ -23,6 +23,7 @@ import * as clientUtils from '@/client/utils/utils'; import * as keysUtils from '@/keys/utils'; import * as validationErrors from '@/validation/errors'; import * as testUtils from '../../utils'; +import { expectRemoteError } from '../../utils'; describe('nodesAdd', () => { const logger = new Logger('nodesAdd test', LogLevel.WARN, [ @@ -116,6 +117,8 @@ describe('nodesAdd', () => { nodesAdd: nodesAdd({ authenticate, nodeManager, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); @@ -174,29 +177,32 @@ describe('nodesAdd', () => { const request = new nodesPB.NodeAddress(); request.setNodeId('vrsc24a1er424epq77dtoveo93meij0pc8ig4uvs9jbeld78n9nl0'); request.setAddress(addressMessage); - await expect( + await expectRemoteError( grpcClient.nodesAdd( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); // Invalid port addressMessage.setHost('127.0.0.1'); addressMessage.setPort(111111); - await expect( + await expectRemoteError( grpcClient.nodesAdd( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); // Invalid nodeid addressMessage.setPort(11111); request.setNodeId('nodeId'); - await expect( + await expectRemoteError( grpcClient.nodesAdd( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); }); }); diff --git a/tests/client/service/nodesClaim.test.ts b/tests/client/service/nodesClaim.test.ts index 07d41e500..bee8c8ad3 100644 --- a/tests/client/service/nodesClaim.test.ts +++ b/tests/client/service/nodesClaim.test.ts @@ -26,6 +26,7 @@ import * as clientUtils from '@/client/utils/utils'; import * as keysUtils from '@/keys/utils'; import * as validationErrors from '@/validation/errors'; import * as testUtils from '../../utils'; +import { expectRemoteError } from '../../utils'; describe('nodesClaim', () => { const logger = new Logger('nodesClaim test', LogLevel.WARN, [ @@ -159,6 +160,8 @@ describe('nodesClaim', () => { authenticate, nodeManager, notificationsManager, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); @@ -228,11 +231,12 @@ describe('nodesClaim', () => { test('cannot claim an invalid node', async () => { const request = new nodesPB.Claim(); request.setNodeId('nodeId'); - await expect( + await expectRemoteError( grpcClient.nodesClaim( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); }); }); diff --git a/tests/client/service/nodesFind.test.ts b/tests/client/service/nodesFind.test.ts index 1197638f5..b01e157a1 100644 --- a/tests/client/service/nodesFind.test.ts +++ b/tests/client/service/nodesFind.test.ts @@ -20,6 +20,7 @@ import * as clientUtils from '@/client/utils/utils'; import * as keysUtils from '@/keys/utils'; import * as validationErrors from '@/validation/errors'; import * as testUtils from '../../utils'; +import { expectRemoteError } from '../../utils'; describe('nodesFind', () => { const logger = new Logger('nodesFind test', LogLevel.WARN, [ @@ -110,8 +111,9 @@ describe('nodesFind', () => { await nodeConnectionManager.start(); const clientService = { nodesFind: nodesFind({ - nodeConnectionManager, authenticate, + nodeConnectionManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); @@ -158,11 +160,12 @@ describe('nodesFind', () => { test('cannot find an invalid node', async () => { const request = new nodesPB.Node(); request.setNodeId('nodeId'); - await expect( + await expectRemoteError( grpcClient.nodesFind( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); }); }); diff --git a/tests/client/service/nodesPing.test.ts b/tests/client/service/nodesPing.test.ts index 0bfcabc97..d4954bb4a 100644 --- a/tests/client/service/nodesPing.test.ts +++ b/tests/client/service/nodesPing.test.ts @@ -22,6 +22,7 @@ import * as clientUtils from '@/client/utils/utils'; import * as keysUtils from '@/keys/utils'; import * as validationErrors from '@/validation/errors'; import * as testUtils from '../../utils'; +import { expectRemoteError } from '../../utils'; describe('nodesPing', () => { const logger = new Logger('nodesPing test', LogLevel.WARN, [ @@ -121,6 +122,7 @@ describe('nodesPing', () => { nodesPing: nodesPing({ authenticate, nodeManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); @@ -173,11 +175,12 @@ describe('nodesPing', () => { test('cannot ping an invalid node', async () => { const request = new nodesPB.Node(); request.setNodeId('nodeId'); - await expect( + await expectRemoteError( grpcClient.nodesPing( request, clientUtils.encodeAuthFromPassword(password), ), - ).rejects.toThrow(validationErrors.ErrorValidation); + validationErrors.ErrorValidation, + ); }); }); diff --git a/tests/client/service/notificationsClear.test.ts b/tests/client/service/notificationsClear.test.ts index 2fab2e233..d8572c584 100644 --- a/tests/client/service/notificationsClear.test.ts +++ b/tests/client/service/notificationsClear.test.ts @@ -135,6 +135,8 @@ describe('notificationsClear', () => { notificationsClear: notificationsClear({ authenticate, notificationsManager, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/notificationsRead.test.ts b/tests/client/service/notificationsRead.test.ts index 1b77af1a3..73690a54d 100644 --- a/tests/client/service/notificationsRead.test.ts +++ b/tests/client/service/notificationsRead.test.ts @@ -209,6 +209,8 @@ describe('notificationsRead', () => { notificationsRead: notificationsRead({ authenticate, notificationsManager, + logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/notificationsSend.test.ts b/tests/client/service/notificationsSend.test.ts index 01764d368..7709f7b47 100644 --- a/tests/client/service/notificationsSend.test.ts +++ b/tests/client/service/notificationsSend.test.ts @@ -144,6 +144,7 @@ describe('notificationsSend', () => { notificationsSend: notificationsSend({ authenticate, notificationsManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/utils.ts b/tests/client/utils.ts index 247b1da8b..036257328 100644 --- a/tests/client/utils.ts +++ b/tests/client/utils.ts @@ -1,16 +1,15 @@ import type { IClientServiceServer } from '@/proto/js/polykey/v1/client_service_grpc_pb'; import type { SessionToken } from '@/sessions/types'; -import type { PolykeyAgent } from '@'; +import type PolykeyAgent from '@/PolykeyAgent'; import type { NodeId } from '@/nodes/types'; import type { Host, Port } from '@/network/types'; import * as grpc from '@grpc/grpc-js'; - import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { ClientServiceService, ClientServiceClient, } from '@/proto/js/polykey/v1/client_service_grpc_pb'; -import { createClientService } from '@/client'; +import createClientService from '@/client/service'; import PolykeyClient from '@/PolykeyClient'; import { promisify } from '@/utils'; import * as grpcUtils from '@/grpc/utils'; @@ -41,6 +40,8 @@ async function openTestClientServer({ grpcServerClient: pkAgent.grpcServerClient, grpcServerAgent: pkAgent.grpcServerAgent, fs: pkAgent.fs, + db: pkAgent.db, + logger: pkAgent.logger, }); const callCredentials = _secure diff --git a/tests/discovery/Discovery.test.ts b/tests/discovery/Discovery.test.ts index 70c4641dd..c11c8d000 100644 --- a/tests/discovery/Discovery.test.ts +++ b/tests/discovery/Discovery.test.ts @@ -1,22 +1,22 @@ import type { ClaimLinkIdentity } from '@/claims/types'; import type { IdentityId, ProviderId } from '@/identities/types'; import type { Host, Port } from '@/network/types'; -import type { Gestalt } from '@/gestalts/types'; import fs from 'fs'; import path from 'path'; import os from 'os'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { DB } from '@matrixai/db'; -import { PolykeyAgent } from '@'; -import { Discovery } from '@/discovery'; -import { GestaltGraph } from '@/gestalts'; -import { IdentitiesManager } from '@/identities'; -import { NodeConnectionManager, NodeGraph, NodeManager } from '@/nodes'; -import { KeyManager } from '@/keys'; -import { ACL } from '@/acl'; -import { Sigchain } from '@/sigchain'; +import PolykeyAgent from '@/PolykeyAgent'; +import Discovery from '@/discovery/Discovery'; +import GestaltGraph from '@/gestalts/GestaltGraph'; +import IdentitiesManager from '@/identities/IdentitiesManager'; +import NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import NodeGraph from '@/nodes/NodeGraph'; +import NodeManager from '@/nodes/NodeManager'; +import KeyManager from '@/keys/KeyManager'; +import ACL from '@/acl/ACL'; +import Sigchain from '@/sigchain/Sigchain'; import Proxy from '@/network/Proxy'; -import { poll } from '@/utils'; import * as nodesUtils from '@/nodes/utils'; import * as claimsUtils from '@/claims/utils'; import * as discoveryErrors from '@/discovery/errors'; @@ -251,34 +251,15 @@ describe('Discovery', () => { logger, }); await discovery.queueDiscoveryByNode(nodeA.keyManager.getNodeId()); - const gestalt = await poll( - async () => { - const gestalts = await poll>( - async () => { - return await gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 3) return true; - return false; - }, - 100, - ); - const gestaltMatrix = gestalt.matrix; - const gestaltNodes = gestalt.nodes; - const gestaltIdentities = gestalt.identities; + await discovery.waitForDrained(); + const gestalt = await gestaltGraph.getGestalts(); + const gestaltMatrix = gestalt[0].matrix; + const gestaltNodes = gestalt[0].nodes; + const gestaltIdentities = gestalt[0].identities; expect(Object.keys(gestaltMatrix)).toHaveLength(3); expect(Object.keys(gestaltNodes)).toHaveLength(2); expect(Object.keys(gestaltIdentities)).toHaveLength(1); - const gestaltString = JSON.stringify(gestalt); + const gestaltString = JSON.stringify(gestalt[0]); expect(gestaltString).toContain( nodesUtils.encodeNodeId(nodeA.keyManager.getNodeId()), ); @@ -304,27 +285,8 @@ describe('Discovery', () => { logger, }); await discovery.queueDiscoveryByIdentity(testToken.providerId, identityId); - const gestalt = await poll( - async () => { - const gestalts = await poll>( - async () => { - return await gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 3) return true; - return false; - }, - 100, - ); + await discovery.waitForDrained(); + const gestalt = (await gestaltGraph.getGestalts())[0]; const gestaltMatrix = gestalt.matrix; const gestaltNodes = gestalt.nodes; const gestaltIdentities = gestalt.identities; @@ -357,27 +319,8 @@ describe('Discovery', () => { logger, }); await discovery.queueDiscoveryByNode(nodeA.keyManager.getNodeId()); - const gestalt1 = await poll( - async () => { - const gestalts = await poll>( - async () => { - return await gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 3) return true; - return false; - }, - 100, - ); + await discovery.waitForDrained(); + const gestalt1 = (await gestaltGraph.getGestalts())[0]; const gestaltMatrix1 = gestalt1.matrix; const gestaltNodes1 = gestalt1.nodes; const gestaltIdentities1 = gestalt1.identities; @@ -410,27 +353,8 @@ describe('Discovery', () => { // Note that eventually we would like to add in a system of revisiting // already discovered vertices, however for now we must do this manually. await discovery.queueDiscoveryByNode(nodeA.keyManager.getNodeId()); - const gestalt2 = await poll( - async () => { - const gestalts = await poll>( - async () => { - return await gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 4) return true; - return false; - }, - 100, - ); + await discovery.waitForDrained(); + const gestalt2 = (await gestaltGraph.getGestalts())[0]; const gestaltMatrix2 = gestalt2.matrix; const gestaltNodes2 = gestalt2.nodes; const gestaltIdentities2 = gestalt2.identities; @@ -470,27 +394,8 @@ describe('Discovery', () => { await discovery.queueDiscoveryByNode(nodeA.keyManager.getNodeId()); await discovery.stop(); await discovery.start(); - const gestalt = await poll( - async () => { - const gestalts = await poll>( - async () => { - return await gestaltGraph.getGestalts(); - }, - (_, result) => { - if (result.length === 1) return true; - return false; - }, - 100, - ); - return gestalts[0]; - }, - (_, result) => { - if (result === undefined) return false; - if (Object.keys(result.matrix).length === 3) return true; - return false; - }, - 100, - ); + await discovery.waitForDrained(); + const gestalt = (await gestaltGraph.getGestalts())[0]; const gestaltMatrix = gestalt.matrix; const gestaltNodes = gestalt.nodes; const gestaltIdentities = gestalt.identities; diff --git a/tests/gestalts/GestaltGraph.test.ts b/tests/gestalts/GestaltGraph.test.ts index fa30c86bd..4b69761ce 100644 --- a/tests/gestalts/GestaltGraph.test.ts +++ b/tests/gestalts/GestaltGraph.test.ts @@ -14,8 +14,8 @@ import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { DB } from '@matrixai/db'; -import { GestaltGraph } from '@/gestalts'; -import { ACL } from '@/acl'; +import GestaltGraph from '@/gestalts/GestaltGraph'; +import ACL from '@/acl/ACL'; import * as gestaltsErrors from '@/gestalts/errors'; import * as gestaltsUtils from '@/gestalts/utils'; import * as keysUtils from '@/keys/utils'; diff --git a/tests/git/utils.test.ts b/tests/git/utils.test.ts index 3f4b6cf9b..e1f59103f 100644 --- a/tests/git/utils.test.ts +++ b/tests/git/utils.test.ts @@ -165,9 +165,11 @@ describe('Git utils', () => { expect(object).toContain(firstCommit.commit.tree); expect(object).toContain(firstCommit.commit.parent[0]); expect(object).toContain(firstCommit.commit.author.name); - expect(object).toContain(firstCommit.commit.author.timestamp); + expect(object).toContain(firstCommit.commit.author.timestamp.toString()); expect(object).toContain(firstCommit.commit.committer.name); - expect(object).toContain(firstCommit.commit.committer.timestamp); + expect(object).toContain( + firstCommit.commit.committer.timestamp.toString(), + ); }); test('wrapped', async () => { const ref = await gitUtils.readObject({ @@ -190,9 +192,11 @@ describe('Git utils', () => { expect(object).toContain(firstCommit.commit.tree); expect(object).toContain(firstCommit.commit.parent[0]); expect(object).toContain(firstCommit.commit.author.name); - expect(object).toContain(firstCommit.commit.author.timestamp); + expect(object).toContain(firstCommit.commit.author.timestamp.toString()); expect(object).toContain(firstCommit.commit.committer.name); - expect(object).toContain(firstCommit.commit.committer.timestamp); + expect(object).toContain( + firstCommit.commit.committer.timestamp.toString(), + ); }); test('deflated', async () => { const ref = await gitUtils.readObject({ @@ -234,9 +238,11 @@ describe('Git utils', () => { expect(object).toContain(firstCommit.commit.tree); expect(object).toContain(firstCommit.commit.parent[0]); expect(object).toContain(firstCommit.commit.author.name); - expect(object).toContain(firstCommit.commit.author.timestamp); + expect(object).toContain(firstCommit.commit.author.timestamp.toString()); expect(object).toContain(firstCommit.commit.committer.name); - expect(object).toContain(firstCommit.commit.committer.timestamp); + expect(object).toContain( + firstCommit.commit.committer.timestamp.toString(), + ); }); }); }); diff --git a/tests/grpc/GRPCClient.test.ts b/tests/grpc/GRPCClient.test.ts index a4f83a1e0..31028187e 100644 --- a/tests/grpc/GRPCClient.test.ts +++ b/tests/grpc/GRPCClient.test.ts @@ -10,13 +10,15 @@ import path from 'path'; import fs from 'fs'; import { DB } from '@matrixai/db'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; -import { utils as keysUtils } from '@/keys'; -import { Session, SessionManager } from '@/sessions'; -import { errors as grpcErrors } from '@/grpc'; +import Session from '@/sessions/Session'; +import SessionManager from '@/sessions/SessionManager'; +import * as keysUtils from '@/keys/utils'; +import * as grpcErrors from '@/grpc/errors'; import * as clientUtils from '@/client/utils'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import * as utils from './utils'; import * as testUtils from '../utils'; +import { expectRemoteError } from '../utils'; describe('GRPCClient', () => { const logger = new Logger('GRPCClient Test', LogLevel.WARN, [ @@ -172,7 +174,7 @@ describe('GRPCClient', () => { const m2 = new utilsPB.EchoMessage(); m2.setChallenge('error'); pCall = client.unary(m2); - await expect(pCall).rejects.toThrow(grpcErrors.ErrorGRPC); + await expectRemoteError(pCall, grpcErrors.ErrorGRPC); meta = await pCall.meta; // Expect reflected reflected session token expect(clientUtils.decodeAuthToSession(meta)).toBe( diff --git a/tests/grpc/GRPCServer.test.ts b/tests/grpc/GRPCServer.test.ts index 2c62b70f9..9b5c54809 100644 --- a/tests/grpc/GRPCServer.test.ts +++ b/tests/grpc/GRPCServer.test.ts @@ -5,11 +5,13 @@ import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { DB } from '@matrixai/db'; -import { GRPCServer, utils as grpcUtils } from '@/grpc'; -import { KeyManager, utils as keysUtils } from '@/keys'; -import { SessionManager } from '@/sessions'; +import GRPCServer from '@/grpc/GRPCServer'; +import KeyManager from '@/keys/KeyManager'; +import SessionManager from '@/sessions/SessionManager'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import * as grpcErrors from '@/grpc/errors'; +import * as grpcUtils from '@/grpc/utils'; +import * as keysUtils from '@/keys/utils'; import * as clientUtils from '@/client/utils'; import * as testGrpcUtils from './utils'; import * as testUtils from '../utils'; diff --git a/tests/grpc/utils.test.ts b/tests/grpc/utils.test.ts index c17f0457d..496f6553b 100644 --- a/tests/grpc/utils.test.ts +++ b/tests/grpc/utils.test.ts @@ -4,6 +4,7 @@ import * as grpc from '@grpc/grpc-js'; import { getLogger } from '@grpc/grpc-js/build/src/logging'; import * as grpcUtils from '@/grpc/utils'; import * as grpcErrors from '@/grpc/errors'; +import * as errors from '@/errors'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import * as utils from './utils'; @@ -57,13 +58,14 @@ describe('GRPC utils', () => { const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); const pCall = unary(messageTo); - await expect(pCall).rejects.toThrow(grpcErrors.ErrorGRPC); + await expect(pCall).rejects.toThrow(errors.ErrorPolykeyRemote); try { await pCall; } catch (e) { // This information comes from the server expect(e.message).toBe('test error'); - expect(e.data).toMatchObject({ + expect(e.cause).toBeInstanceOf(grpcErrors.ErrorGRPC); + expect(e.cause.data).toMatchObject({ grpc: true, }); } @@ -103,7 +105,9 @@ describe('GRPC utils', () => { const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge(challenge); const stream = serverStream(messageTo); - await expect(() => stream.next()).rejects.toThrow(grpcErrors.ErrorGRPC); + await expect(() => stream.next()).rejects.toThrow( + errors.ErrorPolykeyRemote, + ); // The generator will have ended // the internal stream will be automatically destroyed const result = await stream.next(); @@ -274,7 +278,9 @@ describe('GRPC utils', () => { const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); await genDuplex.write(messageTo); - await expect(() => genDuplex.read()).rejects.toThrow(grpcErrors.ErrorGRPC); + await expect(() => genDuplex.read()).rejects.toThrow( + errors.ErrorPolykeyRemote, + ); expect(genDuplex.stream.destroyed).toBe(true); expect(genDuplex.stream.getPeer()).toBe(`127.0.0.1:${port}`); }); @@ -287,9 +293,123 @@ describe('GRPC utils', () => { const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); await expect(() => genDuplex.next(messageTo)).rejects.toThrow( - grpcErrors.ErrorGRPC, + errors.ErrorPolykeyRemote, ); expect(genDuplex.stream.destroyed).toBe(true); expect(genDuplex.stream.getPeer()).toBe(`127.0.0.1:${port}`); }); + test('serialising and deserialising Polykey errors', async () => { + const timestamp = new Date(); + const error = new errors.ErrorPolykey('test error', { + timestamp, + data: { + int: 1, + str: 'one', + }, + }); + error.exitCode = 255; + const serialised = grpcUtils.fromError(error).metadata!; + const stringifiedError = serialised.get('error')[0] as string; + const parsedError = JSON.parse(stringifiedError); + expect(parsedError).toMatchObject({ + type: 'ErrorPolykey', + data: expect.any(Object), + }); + const deserialisedError = grpcUtils.toError({ + name: '', + message: '', + code: 2, + details: '', + metadata: serialised, + }); + expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); + expect(deserialisedError.message).toBe('test error'); + expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykey); + expect(deserialisedError.cause.message).toBe('test error'); + expect(deserialisedError.cause.exitCode).toBe(255); + expect(deserialisedError.cause.timestamp).toEqual(timestamp); + expect(deserialisedError.cause.data).toEqual(error.data); + expect(deserialisedError.cause.stack).toBe(error.stack); + }); + test('serialising and deserialising generic errors', async () => { + const error = new TypeError('test error'); + const serialised = grpcUtils.fromError(error).metadata!; + const stringifiedError = serialised.get('error')[0] as string; + const parsedError = JSON.parse(stringifiedError); + expect(parsedError).toMatchObject({ + type: 'TypeError', + data: expect.any(Object), + }); + const deserialisedError = grpcUtils.toError({ + name: '', + message: '', + code: 2, + details: '', + metadata: serialised, + }); + expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); + expect(deserialisedError.message).toBe('test error'); + expect(deserialisedError.cause).toBeInstanceOf(TypeError); + expect(deserialisedError.cause.message).toBe('test error'); + expect(deserialisedError.cause.stack).toBe(error.stack); + }); + test('serialising and deserialising non-errors', async () => { + const error = 'not an error' as unknown as Error; + const serialised = grpcUtils.fromError(error).metadata!; + const stringifiedError = serialised.get('error')[0] as string; + const parsedError = JSON.parse(stringifiedError); + expect(parsedError).toEqual('not an error'); + const deserialisedError = grpcUtils.toError({ + name: '', + message: '', + code: 2, + details: '', + metadata: serialised, + }); + expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); + expect(deserialisedError.message).toBe(''); + expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykeyUnknown); + expect(deserialisedError.cause.message).toBe(''); + expect(deserialisedError.cause.data).toEqual('not an error'); + }); + test('serialising and deserialising sensitive errors', async () => { + const timestamp = new Date(); + const error = new errors.ErrorPolykey('test error', { + timestamp, + data: { + int: 1, + str: 'one', + }, + }); + error.exitCode = 255; + const serialised = grpcUtils.fromError(error, true).metadata!; + const stringifiedError = serialised.get('error')[0] as string; + const parsedError = JSON.parse(stringifiedError); + // Stack is the only thing that should not be serialised + expect(parsedError).toEqual({ + type: 'ErrorPolykey', + data: { + description: errors.ErrorPolykey.description, + message: 'test error', + exitCode: 255, + timestamp: expect.any(String), + data: error.data, + }, + }); + const deserialisedError = grpcUtils.toError({ + name: '', + message: '', + code: 2, + details: '', + metadata: serialised, + }); + expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); + expect(deserialisedError.message).toBe('test error'); + expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykey); + expect(deserialisedError.cause.message).toBe('test error'); + expect(deserialisedError.cause.exitCode).toBe(255); + expect(deserialisedError.cause.timestamp).toEqual(timestamp); + expect(deserialisedError.cause.data).toEqual(error.data); + expect(deserialisedError.cause.stack).not.toBe(error.stack); + }); }); diff --git a/tests/grpc/utils/GRPCClientTest.ts b/tests/grpc/utils/GRPCClientTest.ts index c4b55b1d1..9cb176377 100644 --- a/tests/grpc/utils/GRPCClientTest.ts +++ b/tests/grpc/utils/GRPCClientTest.ts @@ -1,5 +1,5 @@ import type { Interceptor } from '@grpc/grpc-js'; -import type { Session } from '@/sessions'; +import type Session from '@/sessions/Session'; import type { NodeId } from '@/nodes/types'; import type { Host, Port, TLSConfig, ProxyConfig } from '@/network/types'; import type * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; @@ -7,7 +7,8 @@ import type { ClientReadableStream } from '@grpc/grpc-js/build/src/call'; import type { AsyncGeneratorReadableStreamClient } from '@/grpc/types'; import Logger from '@matrixai/logger'; import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy'; -import { GRPCClient, utils as grpcUtils } from '@/grpc'; +import GRPCClient from '@/grpc/GRPCClient'; +import * as grpcUtils from '@/grpc/utils'; import * as clientUtils from '@/client/utils'; import { TestServiceClient } from '@/proto/js/polykey/v1/test_service_grpc_pb'; diff --git a/tests/grpc/utils/testService.ts b/tests/grpc/utils/testService.ts index 5c3356d7f..38cd50128 100644 --- a/tests/grpc/utils/testService.ts +++ b/tests/grpc/utils/testService.ts @@ -9,7 +9,8 @@ import type { SessionToken } from '@/sessions/types'; import type { ITestServiceServer } from '@/proto/js/polykey/v1/test_service_grpc_pb'; import Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; -import { utils as grpcUtils, errors as grpcErrors } from '@/grpc'; +import * as grpcUtils from '@/grpc/utils'; +import * as grpcErrors from '@/grpc/errors'; import * as clientUtils from '@/client/utils'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import { sleep } from '@/utils'; @@ -43,7 +44,7 @@ function createTestService({ // we'll send back an error callback( grpcUtils.fromError( - new grpcErrors.ErrorGRPC('test error', { grpc: true }), + new grpcErrors.ErrorGRPC('test error', { data: { grpc: true } }), ), ); } else { @@ -67,13 +68,13 @@ function createTestService({ ); call.sendMetadata(meta); } - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); const messageFrom = call.request; const messageTo = new utilsPB.EchoMessage(); const challenge = messageFrom.getChallenge(); if (challenge === 'error') { await genWritable.throw( - new grpcErrors.ErrorGRPC('test error', { grpc: true }), + new grpcErrors.ErrorGRPC('test error', { data: { grpc: true } }), ); } else { // Will send back a number of message @@ -131,7 +132,7 @@ function createTestService({ ); call.sendMetadata(meta); } - const genDuplex = grpcUtils.generatorDuplex(call); + const genDuplex = grpcUtils.generatorDuplex(call, false); const readStatus = await genDuplex.read(); // If nothing to read, end and destroy if (readStatus.done) { @@ -143,7 +144,7 @@ function createTestService({ const incomingMessage = readStatus.value; if (incomingMessage.getChallenge() === 'error') { await genDuplex.throw( - new grpcErrors.ErrorGRPC('test error', { grpc: true }), + new grpcErrors.ErrorGRPC('test error', { data: { grpc: true } }), ); } else { const outgoingMessage = new utilsPB.EchoMessage(); @@ -169,7 +170,7 @@ function createTestService({ // we'll send back an error callback( grpcUtils.fromError( - new grpcErrors.ErrorGRPC('test error', { grpc: true }), + new grpcErrors.ErrorGRPC('test error', { data: { grpc: true } }), ), ); } else { @@ -182,7 +183,7 @@ function createTestService({ serverStreamFail: async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, false); try { const echoMessage = new utilsPB.EchoMessage().setChallenge('Hello!'); for (let i = 0; i < 10; i++) { diff --git a/tests/keys/KeyManager.test.ts b/tests/keys/KeyManager.test.ts index 773b5d3eb..260346bc6 100644 --- a/tests/keys/KeyManager.test.ts +++ b/tests/keys/KeyManager.test.ts @@ -315,7 +315,7 @@ describe('KeyManager', () => { const rootKeyPair1 = keyManager.getRootKeyPair(); const rootCert1 = keyManager.getRootCert(); await sleep(2000); // Let's just make sure there is time diff - await db.put(['test'], 'hello', 'world'); + await db.put(['test', 'hello'], 'world'); // Reset root key pair takes time await keyManager.resetRootKeyPair('password'); expect(keyManager.getRecoveryCode()).toBeDefined(); @@ -339,7 +339,7 @@ describe('KeyManager', () => { ); await db.stop(); await db.start(); - expect(await db.get(['test'], 'hello')).toBe('world'); + expect(await db.get(['test', 'hello'])).toBe('world'); await keyManager.stop(); }); test('can renew root key pair', async () => { @@ -364,7 +364,7 @@ describe('KeyManager', () => { const rootKeyPair1 = keyManager.getRootKeyPair(); const rootCert1 = keyManager.getRootCert(); await sleep(2000); // Let's just make sure there is time diff - await db.put(['test'], 'hello', 'world'); + await db.put(['test', 'hello'], 'world'); await keyManager.renewRootKeyPair('newpassword'); expect(keyManager.getRecoveryCode()).toBeDefined(); const rootKeyPair2 = keyManager.getRootKeyPair(); @@ -393,7 +393,7 @@ describe('KeyManager', () => { expect(keysUtils.certVerified(rootCert1, rootCert2)).toBe(true); await db.stop(); await db.start(); - expect(await db.get(['test'], 'hello')).toBe('world'); + expect(await db.get(['test', 'hello'])).toBe('world'); await keyManager.stop(); }); test('order of certificate chain should be leaf to root', async () => { diff --git a/tests/network/Proxy.test.ts b/tests/network/Proxy.test.ts index 4393c69b9..438d1e2e9 100644 --- a/tests/network/Proxy.test.ts +++ b/tests/network/Proxy.test.ts @@ -6,14 +6,12 @@ import net from 'net'; import tls from 'tls'; import UTP from 'utp-native'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; -import { - Proxy, - utils as networkUtils, - errors as networkErrors, -} from '@/network'; -import * as keysUtils from '@/keys/utils'; import { promisify, promise, timerStart, timerStop, poll } from '@/utils'; -import { utils as nodesUtils } from '@/nodes'; +import Proxy from '@/network/Proxy'; +import * as networkUtils from '@/network/utils'; +import * as networkErrors from '@/network/errors'; +import * as keysUtils from '@/keys/utils'; +import * as nodesUtils from '@/nodes/utils'; import * as testUtils from '../utils'; /** @@ -110,7 +108,7 @@ function tcpServer(end: boolean = false) { describe(Proxy.name, () => { const localHost = '127.0.0.1' as Host; const port = 0 as Port; - const logger = new Logger(`${Proxy.name} test`, LogLevel.WARN, [ + const logger = new Logger(`${Proxy.name} test`, LogLevel.DEBUG, [ new StreamHandler(), ]); const nodeIdABC = testUtils.generateRandomNodeId(); @@ -476,19 +474,19 @@ describe(Proxy.name, () => { ), ).rejects.toThrow(networkErrors.ErrorConnectionStart); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); + expect(utpConnError).not.toHaveBeenCalled(); // The TLS socket throw an error because there's no suitable signature algorithm - expect(tlsSocketError.mock.calls.length).toBe(1); + expect(tlsSocketError).toHaveBeenCalled(); // Expect(tlsSocketError.mock.calls[0][0]).toBeInstanceOf(Error); expect(tlsSocketError.mock.calls[0][0]).toHaveProperty( 'code', 'ERR_SSL_NO_SUITABLE_SIGNATURE_ALGORITHM', ); // The TLS socket end event never was emitted - expect(tlsSocketEnd.mock.calls.length).toBe(0); + expect(tlsSocketEnd).not.toHaveBeenCalled(); // The TLS socket close event is emitted with error - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(true); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(true); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -585,19 +583,19 @@ describe(Proxy.name, () => { ), ).rejects.toThrow('502'); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); + expect(utpConnError).not.toHaveBeenCalled(); // The TLS socket throw an error because there's no suitable signature algorithm - expect(tlsSocketError.mock.calls.length).toBe(1); + expect(tlsSocketError).toHaveBeenCalled(); // Expect(tlsSocketError.mock.calls[0][0]).toBeInstanceOf(Error); expect(tlsSocketError.mock.calls[0][0]).toHaveProperty( 'code', 'ERR_SSL_NO_SUITABLE_SIGNATURE_ALGORITHM', ); // The TLS socket end event never was emitted - expect(tlsSocketEnd.mock.calls.length).toBe(0); + expect(tlsSocketEnd).not.toHaveBeenCalled(); // The TLS socket close event is emitted with error - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(true); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(true); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -705,15 +703,15 @@ describe(Proxy.name, () => { expect(secured).toBe(true); expect(proxy.getConnectionForwardCount()).toBe(0); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); + expect(utpConnError).not.toHaveBeenCalled(); // No TLS socket errors this time // The client side figured that the node id is incorect - expect(tlsSocketError.mock.calls.length).toBe(0); + expect(tlsSocketError).not.toHaveBeenCalled(); // This time the tls socket is ended from the client side - expect(tlsSocketEnd.mock.calls.length).toBe(1); + expect(tlsSocketEnd).toHaveBeenCalled(); // The TLS socket close event is emitted without error - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -754,6 +752,7 @@ describe(Proxy.name, () => { let secured = false; const utpSocket = UTP.createServer(async (utpConn) => { utpConn.on('error', (e) => { + logger.debug(`utpconn error! ${e.message}`); utpConnError(e); }); const tlsSocket = new tls.TLSSocket(utpConn, { @@ -764,9 +763,11 @@ describe(Proxy.name, () => { rejectUnauthorized: false, }); tlsSocket.on('secure', () => { + logger.debug('secure'); secured = true; }); tlsSocket.on('error', (e) => { + logger.debug(`tlsSocket error: ${e.message}`); tlsSocketError(e); }); tlsSocket.on('end', () => { @@ -782,9 +783,11 @@ describe(Proxy.name, () => { } }); tlsSocket.on('close', (hadError) => { + logger.debug('close'); tlsSocketClose(hadError); resolveRemoteClosedP(); }); + logger.debug('lol'); await send(networkUtils.pingBuffer); const punchInterval = setInterval(async () => { await send(networkUtils.pingBuffer); @@ -792,24 +795,28 @@ describe(Proxy.name, () => { await remoteReadyP; clearInterval(punchInterval); }); + const send = async (data: Buffer) => { + logger.debug(`sending message: ${data}`); + const utpSocketSend = promisify(utpSocket.send).bind(utpSocket); + await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); + }; const handleMessage = async (data: Buffer) => { const msg = networkUtils.unserializeNetworkMessage(data); + logger.debug(`received message: ${JSON.stringify(msg)}`); if (msg.type === 'ping') { + logger.debug('sending pong'); await send(networkUtils.pongBuffer); } else if (msg.type === 'pong') { resolveRemoteReadyP(); } }; utpSocket.on('message', handleMessage); - const send = async (data: Buffer) => { - const utpSocketSend = promisify(utpSocket.send).bind(utpSocket); - await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); - }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); await utpSocketListen(0, '127.0.0.1'); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); + logger.debug('connecting'); await expect(() => httpConnect( proxy.getForwardHost(), @@ -820,19 +827,20 @@ describe(Proxy.name, () => { )}`, ), ).rejects.toThrow('526'); + logger.debug('connected'); await expect(remoteReadyP).resolves.toBeUndefined(); expect(secured).toBe(true); expect(proxy.getConnectionForwardCount()).toBe(0); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); + expect(utpConnError).not.toHaveBeenCalled(); // No TLS socket errors this time - // The client side figured taht the node id is incorect - expect(tlsSocketError.mock.calls.length).toBe(0); + // The client side figured that the node id is incorrect + expect(tlsSocketError).not.toHaveBeenCalled(); // This time the tls socket is ended from the client side - expect(tlsSocketEnd.mock.calls.length).toBe(1); + expect(tlsSocketEnd).toHaveBeenCalled(); // The TLS socket close event is emitted without error - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -876,7 +884,9 @@ describe(Proxy.name, () => { const tlsSocketClose = jest.fn(); // This UTP server will hold the connection const utpSocket = UTP.createServer(async (utpConn) => { + const utpLogger = logger.getChild('utpSocket'); utpConn.on('error', (e) => { + utpLogger.debug(`error: ${e.message}`); utpConnError(e); }); const tlsSocket = new tls.TLSSocket(utpConn, { @@ -886,14 +896,17 @@ describe(Proxy.name, () => { requestCert: true, rejectUnauthorized: false, }); + const tlsLogger = utpLogger.getChild('tlsSocket'); tlsSocket.on('secure', () => { + tlsLogger.debug('secure'); resolveRemoteSecureP(); }); tlsSocket.on('error', (e) => { + tlsLogger.debug(`error: ${e.message}`); tlsSocketError(e); }); tlsSocket.on('end', () => { - logger.debug('Reverse: receives tlsSocket ending'); + tlsLogger.debug('Reverse: receives tlsSocket ending'); tlsSocketEnd(); if (utpConn.destroyed) { logger.debug('Reverse: destroys tlsSocket'); @@ -906,11 +919,14 @@ describe(Proxy.name, () => { } }); tlsSocket.on('close', (hadError) => { + tlsLogger.debug('close'); tlsSocketClose(hadError); resolveRemoteClosedP(); }); + logger.debug('sending ping'); await send(networkUtils.pingBuffer); const punchInterval = setInterval(async () => { + logger.debug('sending ping'); await send(networkUtils.pingBuffer); }, 1000); await remoteReadyP; @@ -919,21 +935,26 @@ describe(Proxy.name, () => { const handleMessage = async (data: Buffer) => { const msg = networkUtils.unserializeNetworkMessage(data); if (msg.type === 'ping') { + logger.debug('sending pong'); await send(networkUtils.pongBuffer); } else if (msg.type === 'pong') { + logger.debug('received pong'); resolveRemoteReadyP(); } }; utpSocket.on('message', handleMessage); const send = async (data: Buffer) => { + logger.debug('sending'); const utpSocketSend = promisify(utpSocket.send).bind(utpSocket); await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); + logger.debug('listening'); await utpSocketListen(0, '127.0.0.1'); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); + logger.debug('opening forward connection'); await proxy.openConnectionForward( serverNodeId, utpSocketHost as Host, @@ -942,6 +963,7 @@ describe(Proxy.name, () => { await expect(remoteReadyP).resolves.toBeUndefined(); await expect(remoteSecureP).resolves.toBeUndefined(); // Opening a duplicate connection is noop + logger.debug('opening 2nd forward connection'); await proxy.openConnectionForward( serverNodeId, utpSocketHost as Host, @@ -954,11 +976,11 @@ describe(Proxy.name, () => { ); expect(proxy.getConnectionForwardCount()).toBe(0); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); - expect(tlsSocketEnd.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(utpConnError).not.toHaveBeenCalled(); + expect(tlsSocketError).not.toHaveBeenCalled(); + expect(tlsSocketEnd).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1102,13 +1124,13 @@ describe(Proxy.name, () => { 100, ), ).resolves.toBe(0); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); + expect(utpConnError).not.toHaveBeenCalled(); + expect(tlsSocketError).not.toHaveBeenCalled(); // This time the reverse side initiates the end // Therefore, this handler is removed - expect(tlsSocketEnd.mock.calls.length).toBe(0); - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(tlsSocketEnd).not.toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1250,14 +1272,14 @@ describe(Proxy.name, () => { utpSocketPort as Port, ); expect(proxy.getConnectionForwardCount()).toBe(0); - expect(clientSocketEnd.mock.calls.length).toBe(1); + expect(clientSocketEnd).toHaveBeenCalled(); await expect(localClosedP).resolves.toBeUndefined(); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); - expect(tlsSocketEnd.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(utpConnError).not.toHaveBeenCalled(); + expect(tlsSocketError).not.toHaveBeenCalled(); + expect(tlsSocketEnd).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1408,7 +1430,7 @@ describe(Proxy.name, () => { tlsSocket_!.destroy(); logger.debug('Reverse: finishes tlsSocket ending'); await expect(localClosedP).resolves.toBeUndefined(); - expect(clientSocketEnd.mock.calls.length).toBe(1); + expect(clientSocketEnd).toHaveBeenCalled(); await expect(remoteClosedP).resolves.toBeUndefined(); // Connection count should reach 0 eventually await expect( @@ -1423,13 +1445,13 @@ describe(Proxy.name, () => { 100, ), ).resolves.toBe(0); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); + expect(utpConnError).not.toHaveBeenCalled(); + expect(tlsSocketError).not.toHaveBeenCalled(); // This time the reverse side initiates the end // Therefore, this handler is removed - expect(tlsSocketEnd.mock.calls.length).toBe(0); - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(tlsSocketEnd).not.toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1584,11 +1606,11 @@ describe(Proxy.name, () => { 100, ), ).resolves.toBe(0); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); - expect(tlsSocketEnd.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(utpConnError).not.toHaveBeenCalled(); + expect(tlsSocketError).not.toHaveBeenCalled(); + expect(tlsSocketEnd).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1715,11 +1737,11 @@ describe(Proxy.name, () => { ); await expect(localClosedP).resolves.toBeUndefined(); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); - expect(tlsSocketEnd.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(utpConnError).not.toHaveBeenCalled(); + expect(tlsSocketError).not.toHaveBeenCalled(); + expect(tlsSocketEnd).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1832,11 +1854,11 @@ describe(Proxy.name, () => { // When ErrorConnectionTimeout is triggered // This results in the destruction of the socket await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); - expect(tlsSocketEnd.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(utpConnError).not.toHaveBeenCalled(); + expect(tlsSocketError).not.toHaveBeenCalled(); + expect(tlsSocketEnd).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1974,11 +1996,11 @@ describe(Proxy.name, () => { 100, ), ).resolves.toBe(0); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); - expect(tlsSocketEnd.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls.length).toBe(1); - expect(tlsSocketClose.mock.calls[0][0]).toBe(false); + expect(utpConnError).not.toHaveBeenCalled(); + expect(tlsSocketError).not.toHaveBeenCalled(); + expect(tlsSocketEnd).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalled(); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); diff --git a/tests/nodes/NodeConnection.test.ts b/tests/nodes/NodeConnection.test.ts index 52d1ce674..7c842724d 100644 --- a/tests/nodes/NodeConnection.test.ts +++ b/tests/nodes/NodeConnection.test.ts @@ -1,6 +1,7 @@ import type { AddressInfo } from 'net'; import type { ConnectionInfo, Host, Port, TLSConfig } from '@/network/types'; import type { NodeId, NodeInfo } from '@/nodes/types'; +import type { Server } from '@grpc/grpc-js'; import net from 'net'; import os from 'os'; import path from 'path'; @@ -18,9 +19,6 @@ import NodeManager from '@/nodes/NodeManager'; import VaultManager from '@/vaults/VaultManager'; import KeyManager from '@/keys/KeyManager'; import * as keysUtils from '@/keys/utils'; -import GRPCServer from '@/grpc/GRPCServer'; -import { AgentServiceService } from '@/proto/js/polykey/v1/agent_service_grpc_pb'; -import createAgentService from '@/agent/service'; import GRPCClientAgent from '@/agent/GRPCClientAgent'; import ACL from '@/acl/ACL'; import GestaltGraph from '@/gestalts/GestaltGraph'; @@ -37,11 +35,12 @@ import * as agentErrors from '@/agent/errors'; import * as grpcUtils from '@/grpc/utils'; import * as testUtils from '../utils'; import * as grpcTestUtils from '../grpc/utils'; +import * as agentTestUtils from '../agent/utils'; const destroyCallback = async () => {}; // Dummy nodeConnectionManager -// We only need the hole punch function and frankly its not used in testing here +// We only need the hole punch function, and frankly it's not used in testing here // This is really dirty so don't do this outside of testing EVER const dummyNodeConnectionManager = { openConnection: async (_host, _port) => { @@ -97,9 +96,10 @@ describe(`${NodeConnection.name} test`, () => { let sourceNodeId: NodeId; let clientKeyManager: KeyManager; const authToken = 'AUTH'; - let clientproxy: Proxy; + let clientProxy: Proxy; - let agentServer: GRPCServer; + let agentServer: Server; + let serverPort: Port; let tlsConfig: TLSConfig; const localHost = '127.0.0.1' as Host; @@ -266,7 +266,8 @@ describe(`${NodeConnection.name} test`, () => { logger: logger, }); await serverGestaltGraph.setNode(node); - const agentService = createAgentService({ + [agentServer, serverPort] = await agentTestUtils.openTestAgentServer({ + db: serverDb, keyManager: serverKeyManager, vaultManager: serverVaultManager, nodeConnectionManager: dummyNodeConnectionManager, @@ -277,17 +278,11 @@ describe(`${NodeConnection.name} test`, () => { acl: serverACL, gestaltGraph: serverGestaltGraph, proxy: serverProxy, - }); - agentServer = new GRPCServer({ logger: logger, }); - await agentServer.start({ - services: [[AgentServiceService, agentService]], - host: localHost, - }); await serverProxy.start({ serverHost: localHost, - serverPort: agentServer.getPort(), + serverPort: serverPort, proxyHost: localHost, tlsConfig: serverTLSConfig, }); @@ -311,18 +306,18 @@ describe(`${NodeConnection.name} test`, () => { }; sourceNodeId = clientKeyManager.getNodeId(); - clientproxy = new Proxy({ + clientProxy = new Proxy({ authToken: authToken, logger: logger, }); - await clientproxy.start({ + await clientProxy.start({ forwardHost: localHost, tlsConfig: clientTLSConfig, proxyHost: localHost, serverHost: localHost, serverPort: 0 as Port, }); - sourcePort = clientproxy.getProxyPort(); + sourcePort = clientProxy.getProxyPort(); // Other setup const globalKeyPair = await testUtils.setupGlobalKeypair(); @@ -339,7 +334,7 @@ describe(`${NodeConnection.name} test`, () => { }, global.polykeyStartupTimeout * 2); afterEach(async () => { - await clientproxy.stop(); + await clientProxy.stop(); await clientKeyManager.stop(); await clientKeyManager.destroy(); await fs.promises.rm(clientDataDir, { @@ -360,7 +355,7 @@ describe(`${NodeConnection.name} test`, () => { await serverNodeConnectionManager.stop(); await serverNotificationsManager.stop(); await serverNotificationsManager.destroy(); - await agentServer.stop(); + await agentTestUtils.closeTestAgentServer(agentServer); await serverProxy.stop(); await serverKeyManager.stop(); await serverKeyManager.destroy(); @@ -378,7 +373,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -394,7 +389,7 @@ describe(`${NodeConnection.name} test`, () => { // Explicitly close the connection such that there's no interference in next test await serverProxy.closeConnectionReverse( localHost, - clientproxy.getProxyPort(), + clientProxy.getProxyPort(), ); }); test('connects to its target (via direct connection)', async () => { @@ -402,7 +397,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -418,8 +413,7 @@ describe(`${NodeConnection.name} test`, () => { }, (e) => { if (e instanceof networkErrors.ErrorConnectionNotComposed) return false; - if (e instanceof networkErrors.ErrorConnectionNotRunning) return false; - return true; + return !(e instanceof networkErrors.ErrorConnectionNotRunning); }, ); expect(connInfo).toBeDefined(); @@ -434,7 +428,7 @@ describe(`${NodeConnection.name} test`, () => { await conn.destroy(); }); test('connects to its target but proxies connect first', async () => { - await clientproxy.openConnectionForward( + await clientProxy.openConnectionForward( targetNodeId, localHost, targetPort, @@ -443,7 +437,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -459,8 +453,7 @@ describe(`${NodeConnection.name} test`, () => { }, (e) => { if (e instanceof networkErrors.ErrorConnectionNotComposed) return false; - if (e instanceof networkErrors.ErrorConnectionNotRunning) return false; - return true; + return !(e instanceof networkErrors.ErrorConnectionNotRunning); }, ); expect(connInfo).toBeDefined(); @@ -490,7 +483,7 @@ describe(`${NodeConnection.name} test`, () => { const killSelf = jest.fn(); nodeConnection = await NodeConnection.createNodeConnection({ connConnectTime: 500, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, logger: logger, nodeConnectionManager: dummyNodeConnectionManager, @@ -525,7 +518,7 @@ describe(`${NodeConnection.name} test`, () => { targetHost: '128.0.0.1' as Host, targetPort: 12345 as Port, connConnectTime: 300, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -541,7 +534,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -562,7 +555,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -600,7 +593,7 @@ describe(`${NodeConnection.name} test`, () => { const killSelf = jest.fn(); const nodeConnectionP = NodeConnection.createNodeConnection({ connConnectTime: 500, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, logger: logger, nodeConnectionManager: dummyNodeConnectionManager, @@ -643,7 +636,7 @@ describe(`${NodeConnection.name} test`, () => { const killSelf = jest.fn(); const nodeConnectionP = NodeConnection.createNodeConnection({ connConnectTime: 500, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, logger: logger, nodeConnectionManager: dummyNodeConnectionManager, @@ -681,7 +674,7 @@ describe(`${NodeConnection.name} test`, () => { const killSelf = jest.fn(); nodeConnection = await NodeConnection.createNodeConnection({ connConnectTime: 500, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, logger: logger, nodeConnectionManager: dummyNodeConnectionManager, @@ -743,7 +736,7 @@ describe(`${NodeConnection.name} test`, () => { const killSelfP = promise(); nodeConnection = await NodeConnection.createNodeConnection({ connConnectTime: 2000, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, logger: logger, nodeConnectionManager: dummyNodeConnectionManager, @@ -812,7 +805,7 @@ describe(`${NodeConnection.name} test`, () => { const killSelfP = promise(); nodeConnection = await NodeConnection.createNodeConnection({ connConnectTime: 2000, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, logger: logger, nodeConnectionManager: dummyNodeConnectionManager, diff --git a/tests/nodes/NodeConnectionManager.lifecycle.test.ts b/tests/nodes/NodeConnectionManager.lifecycle.test.ts index 7bb154f36..66961ca1a 100644 --- a/tests/nodes/NodeConnectionManager.lifecycle.test.ts +++ b/tests/nodes/NodeConnectionManager.lifecycle.test.ts @@ -5,6 +5,7 @@ import path from 'path'; import os from 'os'; import { DB } from '@matrixai/db'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +import { withF } from '@matrixai/resources'; import { IdInternal } from '@matrixai/id'; import PolykeyAgent from '@/PolykeyAgent'; import KeyManager from '@/keys/KeyManager'; @@ -16,7 +17,6 @@ import * as nodesUtils from '@/nodes/utils'; import * as nodesErrors from '@/nodes/errors'; import * as keysUtils from '@/keys/utils'; import * as grpcUtils from '@/grpc/utils'; -import { withF } from '@/utils'; describe(`${NodeConnectionManager.name} lifecycle test`, () => { const logger = new Logger( diff --git a/tests/nodes/NodeManager.test.ts b/tests/nodes/NodeManager.test.ts index f3de57cd8..0ac96ec27 100644 --- a/tests/nodes/NodeManager.test.ts +++ b/tests/nodes/NodeManager.test.ts @@ -321,8 +321,10 @@ describe(`${NodeManager.name} test`, () => { // Make sure to remove any side-effects after each test afterEach(async () => { - await x.sigchain.clearDB(); - await y.sigchain.clearDB(); + await x.sigchain.stop(); + await x.sigchain.start({ fresh: true }); + await y.sigchain.stop(); + await y.sigchain.start({ fresh: true }); }); test('can successfully cross sign a claim', async () => { @@ -332,10 +334,6 @@ describe(`${NodeManager.name} test`, () => { // 4. X <- sends doubly signed claim (X's intermediary) <- Y await y.nodeManager.claimNode(xNodeId); - // Check both sigchain locks are released - expect(x.sigchain.locked).toBe(false); - expect(y.sigchain.locked).toBe(false); - // Check X's sigchain state const xChain = await x.sigchain.getChainData(); expect(Object.keys(xChain).length).toBe(1); diff --git a/tests/notifications/NotificationsManager.test.ts b/tests/notifications/NotificationsManager.test.ts index cd3e1eaaa..37be01f56 100644 --- a/tests/notifications/NotificationsManager.test.ts +++ b/tests/notifications/NotificationsManager.test.ts @@ -277,28 +277,26 @@ describe('NotificationsManager', () => { pull: null, } as VaultActions, }; - await expect(async () => + + await testUtils.expectRemoteError( notificationsManager.sendNotification( receiver.keyManager.getNodeId(), generalNotification, ), - ).rejects.toThrow( notificationsErrors.ErrorNotificationsPermissionsNotFound, ); - await expect(async () => + await testUtils.expectRemoteError( notificationsManager.sendNotification( receiver.keyManager.getNodeId(), gestaltNotification, ), - ).rejects.toThrow( notificationsErrors.ErrorNotificationsPermissionsNotFound, ); - await expect(async () => + await testUtils.expectRemoteError( notificationsManager.sendNotification( receiver.keyManager.getNodeId(), vaultNotification, ), - ).rejects.toThrow( notificationsErrors.ErrorNotificationsPermissionsNotFound, ); const receivedNotifications = diff --git a/tests/sessions/SessionManager.test.ts b/tests/sessions/SessionManager.test.ts index 31461996b..bf479885b 100644 --- a/tests/sessions/SessionManager.test.ts +++ b/tests/sessions/SessionManager.test.ts @@ -3,8 +3,10 @@ import os from 'os'; import path from 'path'; import { DB } from '@matrixai/db'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; -import { KeyManager, utils as keysUtils } from '@/keys'; -import { SessionManager, errors as sessionsErrors } from '@/sessions'; +import KeyManager from '@/keys/KeyManager'; +import * as keysUtils from '@/keys/utils'; +import SessionManager from '@/sessions/SessionManager'; +import * as sessionsErrors from '@/sessions/errors'; import { sleep } from '@/utils'; import * as testUtils from '../utils'; diff --git a/tests/sigchain/Sigchain.test.ts b/tests/sigchain/Sigchain.test.ts index b6ff170ef..e53a4c67f 100644 --- a/tests/sigchain/Sigchain.test.ts +++ b/tests/sigchain/Sigchain.test.ts @@ -6,11 +6,12 @@ import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { DB } from '@matrixai/db'; -import { KeyManager, utils as keysUtils } from '@/keys'; -import { Sigchain } from '@/sigchain'; +import KeyManager from '@/keys/KeyManager'; +import Sigchain from '@/sigchain/Sigchain'; import * as claimsUtils from '@/claims/utils'; import * as sigchainErrors from '@/sigchain/errors'; -import { utils as nodesUtils } from '@/nodes'; +import * as nodesUtils from '@/nodes/utils'; +import * as keysUtils from '@/keys/utils'; import * as testUtils from '../utils'; describe('Sigchain', () => { @@ -92,7 +93,7 @@ describe('Sigchain', () => { }); }); - test('session readiness', async () => { + test('sigchain readiness', async () => { const sigchain = await Sigchain.createSigchain({ keyManager, db, logger }); await expect(async () => { await sigchain.destroy(); @@ -104,13 +105,13 @@ describe('Sigchain', () => { await expect(async () => { await sigchain.start(); }).rejects.toThrow(sigchainErrors.ErrorSigchainDestroyed); - await expect(async () => { - await sigchain.getSequenceNumber(); - }).rejects.toThrow(sigchainErrors.ErrorSigchainNotRunning); }); test('async start initialises the sequence number', async () => { const sigchain = await Sigchain.createSigchain({ keyManager, db, logger }); - const sequenceNumber = await sigchain.getSequenceNumber(); + const sequenceNumber = await sigchain.withTransactionF(async (tran) => + // @ts-ignore - get protected method + sigchain.getSequenceNumber(tran), + ); expect(sequenceNumber).toBe(0); await sigchain.stop(); }); @@ -248,8 +249,14 @@ describe('Sigchain', () => { // Create a claim // Firstly, check that we can add an existing claim if it's the first claim // in the sigchain - const hPrev1 = await sigchain.getHashPrevious(); - const seq1 = await sigchain.getSequenceNumber(); + const hPrev1 = await sigchain.withTransactionF(async (tran) => + // @ts-ignore - get protected method + sigchain.getHashPrevious(tran), + ); + const seq1 = await sigchain.withTransactionF(async (tran) => + // @ts-ignore - get protected method + sigchain.getSequenceNumber(tran), + ); expect(hPrev1).toBeNull(); expect(seq1).toBe(0); const claim1 = await claimsUtils.createClaim({ @@ -264,8 +271,14 @@ describe('Sigchain', () => { kid: nodeIdAEncoded, }); await sigchain.addExistingClaim(claim1); - const hPrev2 = await sigchain.getHashPrevious(); - const seq2 = await sigchain.getSequenceNumber(); + const hPrev2 = await sigchain.withTransactionF(async (tran) => + // @ts-ignore - get protected method + sigchain.getHashPrevious(tran), + ); + const seq2 = await sigchain.withTransactionF(async (tran) => + // @ts-ignore - get protected method + sigchain.getSequenceNumber(tran), + ); expect(hPrev2).not.toBeNull(); expect(seq2).toBe(1); @@ -282,8 +295,14 @@ describe('Sigchain', () => { kid: nodeIdAEncoded, }); await sigchain.addExistingClaim(claim2); - const hPrev3 = await sigchain.getHashPrevious(); - const seq3 = await sigchain.getSequenceNumber(); + const hPrev3 = await sigchain.withTransactionF(async (tran) => + // @ts-ignore - get protected method + sigchain.getHashPrevious(tran), + ); + const seq3 = await sigchain.withTransactionF(async (tran) => + // @ts-ignore - get protected method + sigchain.getSequenceNumber(tran), + ); expect(hPrev3).not.toBeNull(); expect(seq3).toBe(2); diff --git a/tests/utils.test.ts b/tests/utils.test.ts index 5f6ee891e..1896fbedc 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -1,6 +1,4 @@ -import type { ResourceAcquire } from '@/utils'; import os from 'os'; -import { Mutex } from 'async-mutex'; import * as utils from '@/utils'; describe('utils', () => { @@ -15,247 +13,4 @@ describe('utils', () => { expect(p).toBe(`${homeDir}/AppData/Local/polykey`); } }); - test('withF resource context', async () => { - // No resources - const result1 = await utils.withF([], async () => { - return 'bar'; - }); - expect(result1).toBe('bar'); - // Noop resource - const result2 = await utils.withF( - [ - async () => { - return [async () => {}]; - }, - ], - async () => { - return 'foo'; - }, - ); - expect(result2).toBe('foo'); - // Counter resource - let counter = 1; - const result3 = await utils.withF( - [ - async () => { - counter++; - return [ - async () => { - counter--; - }, - counter, - ]; - }, - ], - async ([c]) => { - expect(c).toBe(2); - return c / 2; - }, - ); - expect(result3).toBe(1); - expect(counter).toBe(1); - // Multiple resources - const result4 = await utils.withF( - [ - async () => { - return [async () => {}, 123]; - }, - async () => { - return [async () => {}]; - }, - async () => { - return [async () => {}, 'hello world']; - }, - ], - async ([n, u, s]) => { - expect(u).toBe(undefined); - return [n, s]; - }, - ); - expect(result4).toStrictEqual([123, 'hello world']); - // Multiple resources, but only take the first - const result5 = await utils.withF( - [ - async () => { - return [async () => {}, 123]; - }, - async () => { - return [async () => {}]; - }, - async () => { - return [async () => {}, 'hello world']; - }, - ], - async ([n]) => { - return n; - }, - ); - expect(result5).toBe(123); - // Multiple resources outside requires type declaration - const resourceAcquires6: [ - ResourceAcquire, - ResourceAcquire, - ResourceAcquire, - ] = [ - async () => { - return [async () => {}, 123]; - }, - async () => { - return [async () => {}]; - }, - async () => { - return [async () => {}, 'hello world']; - }, - ]; - const result6 = await utils.withF(resourceAcquires6, async ([n, u, s]) => { - expect(u).toBe(undefined); - return [n, s]; - }); - expect(result6).toStrictEqual([123, 'hello world']); - // Multiple resources outside can also use const - const resourceAcquires7 = [ - async () => { - return [async () => {}, 123] as const; - }, - async () => { - return [async () => {}] as const; - }, - async () => { - return [async () => {}, 'hello world'] as const; - }, - ] as const; - const result7 = await utils.withF(resourceAcquires7, async ([n, u, s]) => { - expect(u).toBe(undefined); - return [n, s]; - }); - expect(result7).toStrictEqual([123, 'hello world']); - // It must be given a explicit type, or `as const` can be used internally - const acquire8: ResourceAcquire = async () => { - return [async () => {}, 123]; - }; - const result8 = await utils.withF([acquire8], async () => { - return 'done'; - }); - expect(result8).toBe('done'); - const acquire9 = async () => { - return [async () => {}, 123] as const; - }; - const result9 = await utils.withF([acquire9], async () => { - return 'done'; - }); - expect(result9).toBe('done'); - // Order of acquisition is left to right - // Order of release is right ot left - const lock1 = new Mutex(); - const lock2 = new Mutex(); - const acquireOrder: Array = []; - const releaseOrder: Array = []; - await utils.withF( - [ - async () => { - const release = await lock1.acquire(); - acquireOrder.push(lock1); - return [ - async () => { - releaseOrder.push(lock1); - release(); - }, - lock1, - ]; - }, - async () => { - const release = await lock2.acquire(); - acquireOrder.push(lock2); - return [ - async () => { - releaseOrder.push(lock2); - release(); - }, - lock2, - ]; - }, - ], - async ([l1, l2]) => { - expect(l1.isLocked()).toBe(true); - expect(l2.isLocked()).toBe(true); - }, - ); - expect(acquireOrder).toStrictEqual([lock1, lock2]); - expect(releaseOrder).toStrictEqual([lock2, lock1]); - }); - test('withG resource context', async () => { - // No resources - const g1 = utils.withG([], async function* () { - yield 'first'; - yield 'second'; - return 'last'; - }); - expect(await g1.next()).toStrictEqual({ value: 'first', done: false }); - expect(await g1.next()).toStrictEqual({ value: 'second', done: false }); - expect(await g1.next()).toStrictEqual({ value: 'last', done: true }); - // Noop resource - const g2 = await utils.withG( - [ - async () => { - return [async () => {}]; - }, - ], - async function* () { - yield 'first'; - return 'last'; - }, - ); - expect(await g2.next()).toStrictEqual({ value: 'first', done: false }); - expect(await g2.next()).toStrictEqual({ value: 'last', done: true }); - // Order of acquisition is left to right - // Order of release is right ot left - const lock1 = new Mutex(); - const lock2 = new Mutex(); - const acquireOrder: Array = []; - const releaseOrder: Array = []; - const g3 = utils.withG( - [ - async () => { - const release = await lock1.acquire(); - acquireOrder.push(lock1); - return [ - async () => { - releaseOrder.push(lock1); - release(); - }, - lock1, - ]; - }, - async () => { - const release = await lock2.acquire(); - acquireOrder.push(lock2); - return [ - async () => { - releaseOrder.push(lock2); - release(); - }, - lock2, - ]; - }, - ], - async function* ([l1, l2]) { - expect(l1.isLocked()).toBe(true); - expect(l2.isLocked()).toBe(true); - yield 'first'; - yield 'second'; - return 'last'; - }, - ); - expect(await g3.next()).toStrictEqual({ value: 'first', done: false }); - expect(lock1.isLocked()).toBe(true); - expect(lock2.isLocked()).toBe(true); - expect(await g3.next()).toStrictEqual({ value: 'second', done: false }); - expect(lock1.isLocked()).toBe(true); - expect(lock2.isLocked()).toBe(true); - expect(await g3.next()).toStrictEqual({ value: 'last', done: true }); - expect(lock1.isLocked()).toBe(false); - expect(lock2.isLocked()).toBe(false); - expect(acquireOrder).toStrictEqual([lock1, lock2]); - expect(releaseOrder).toStrictEqual([lock2, lock1]); - }); }); diff --git a/tests/utils.ts b/tests/utils.ts index 3f446b465..38bd48fcd 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -13,6 +13,7 @@ import * as clientUtils from '@/client/utils'; import * as keysUtils from '@/keys/utils'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import { sleep } from '@/utils'; +import * as errors from '@/errors'; import config from '@/config'; /** @@ -184,4 +185,21 @@ function generateRandomNodeId(): NodeId { return IdInternal.fromString(random); } -export { setupGlobalKeypair, setupGlobalAgent, generateRandomNodeId }; +const expectRemoteError = async ( + promise: Promise, + error, +): Promise => { + await expect(promise).rejects.toThrow(errors.ErrorPolykeyRemote); + try { + return await promise; + } catch (e) { + expect(e.cause).toBeInstanceOf(error); + } +}; + +export { + setupGlobalKeypair, + generateRandomNodeId, + expectRemoteError, + setupGlobalAgent, +}; diff --git a/tests/vaults/VaultInternal.test.ts b/tests/vaults/VaultInternal.test.ts index 34f03d70c..86c283baf 100644 --- a/tests/vaults/VaultInternal.test.ts +++ b/tests/vaults/VaultInternal.test.ts @@ -1,7 +1,7 @@ import type { VaultId } from '@/vaults/types'; import type { Vault } from '@/vaults/Vault'; import type KeyManager from '@/keys/KeyManager'; -import type { DBDomain, DBLevel } from '@matrixai/db'; +import type { LevelPath } from '@matrixai/db'; import os from 'os'; import path from 'path'; import fs from 'fs'; @@ -35,8 +35,7 @@ describe('VaultInternal', () => { let efs: EncryptedFS; let db: DB; - let vaultsDb: DBLevel; - let vaultsDbDomain: DBDomain; + let vaultsDbPath: LevelPath; const fakeKeyManager = { getNodeId: () => { @@ -79,8 +78,7 @@ describe('VaultInternal', () => { fs: fs, logger: logger, }); - vaultsDbDomain = ['vaults']; - vaultsDb = await db.level(vaultsDbDomain[0]); + vaultsDbPath = ['vaults']; vaultId = vaultsUtils.generateVaultId(); vault = await VaultInternal.createVaultInternal({ @@ -90,8 +88,7 @@ describe('VaultInternal', () => { logger, fresh: true, db, - vaultsDb, - vaultsDbDomain, + vaultsDbPath, vaultName: 'testVault', }); }); @@ -152,8 +149,7 @@ describe('VaultInternal', () => { fresh: false, db, vaultName: 'testVault1', - vaultsDb, - vaultsDbDomain, + vaultsDbPath, }); await vault.readF(async (efs) => { expect((await efs.readFile('secret-1')).toString()).toStrictEqual( @@ -494,8 +490,11 @@ describe('VaultInternal', () => { test('cannot commit when the remote field is set', async () => { // Write remote metadata await db.put( - [...vaultsDbDomain, vaultsUtils.encodeVaultId(vaultId)], - VaultInternal.remoteKey, + [ + ...vaultsDbPath, + vaultsUtils.encodeVaultId(vaultId), + VaultInternal.remoteKey, + ], { remoteNode: '', remoteVault: '' }, ); const commit = (await vault.log(undefined, 1))[0]; @@ -510,30 +509,34 @@ describe('VaultInternal', () => { }), ).rejects.toThrow(vaultsErrors.ErrorVaultRemoteDefined); }); - test('cannot checkout old commits after branching commit', async () => { - await vault.writeF(async (efs) => { - await efs.writeFile('test1', 'testdata1'); - }); - const secondCommit = (await vault.log(undefined, 1))[0].commitId; - await vault.writeF(async (efs) => { - await efs.writeFile('test2', 'testdata2'); - }); - const thirdCommit = (await vault.log(undefined, 1))[0].commitId; - await vault.writeF(async (efs) => { - await efs.writeFile('test3', 'testdata3'); - }); - const fourthCommit = (await vault.log(undefined, 1))[0].commitId; - await vault.version(secondCommit); - await vault.writeF(async (efs) => { - await efs.writeFile('test4', 'testdata4'); - }); - await expect(() => { - return vault.version(thirdCommit); - }).rejects.toThrow(); - await expect(() => { - return vault.version(fourthCommit); - }).rejects.toThrow(); - }); + test( + 'cannot checkout old commits after branching commit', + async () => { + await vault.writeF(async (efs) => { + await efs.writeFile('test1', 'testdata1'); + }); + const secondCommit = (await vault.log(undefined, 1))[0].commitId; + await vault.writeF(async (efs) => { + await efs.writeFile('test2', 'testdata2'); + }); + const thirdCommit = (await vault.log(undefined, 1))[0].commitId; + await vault.writeF(async (efs) => { + await efs.writeFile('test3', 'testdata3'); + }); + const fourthCommit = (await vault.log(undefined, 1))[0].commitId; + await vault.version(secondCommit); + await vault.writeF(async (efs) => { + await efs.writeFile('test4', 'testdata4'); + }); + await expect(() => { + return vault.version(thirdCommit); + }).rejects.toThrow(); + await expect(() => { + return vault.version(fourthCommit); + }).rejects.toThrow(); + }, + global.defaultTimeout, + ); test('can recover from dirty state', async () => { await vault.writeF(async (efs) => { await efs.writeFile('secret-1', 'secret-content'); @@ -547,11 +550,11 @@ describe('VaultInternal', () => { await vaultEFS.writeFile('dirty', 'dirtyData'); await vaultEFS.writeFile('secret-1', 'dirtyData'); // Setting dirty flag true - const vaultMetadataDbDomain = [ - ...vaultsDbDomain, + const vaultMetadataDbPath = [ + ...vaultsDbPath, vaultsUtils.encodeVaultId(vaultId), ]; - await db.put(vaultMetadataDbDomain, VaultInternal.dirtyKey, true); + await db.put([...vaultMetadataDbPath, VaultInternal.dirtyKey], true); // Restarting vault await vault.stop(); @@ -607,11 +610,11 @@ describe('VaultInternal', () => { }); // Setting dirty flag true - const vaultMetadataDbDomain = [ - ...vaultsDbDomain, + const vaultMetadataDbPath = [ + ...vaultsDbPath, vaultsUtils.encodeVaultId(vaultId), ]; - await db.put(vaultMetadataDbDomain, VaultInternal.dirtyKey, true); + await db.put([...vaultMetadataDbPath, VaultInternal.dirtyKey], true); // Restarting vault await vault.stop(); @@ -735,7 +738,7 @@ describe('VaultInternal', () => { // @ts-ignore: kidnap lock const lock = vault.lock; // Hold a write lock - const releaseWrite = await lock.acquireWrite(); + const [releaseWrite] = await lock.write()(); let finished = false; const writeP = vault.writeF(async () => { @@ -743,17 +746,17 @@ describe('VaultInternal', () => { }); await sleep(waitDelay); expect(finished).toBe(false); - releaseWrite(); + await releaseWrite(); await writeP; expect(finished).toBe(true); - const releaseRead = await lock.acquireRead(); + const [releaseRead] = await lock.read()(); finished = false; const writeP2 = vault.writeF(async () => { finished = true; }); await sleep(waitDelay); - releaseRead(); + await releaseRead(); await writeP2; expect(finished).toBe(true); }); @@ -761,7 +764,7 @@ describe('VaultInternal', () => { // @ts-ignore: kidnap lock const lock = vault.lock; // Hold a write lock - const releaseWrite = await lock.acquireWrite(); + const [releaseWrite] = await lock.write()(); let finished = false; const writeGen = vault.writeG(async function* () { @@ -772,11 +775,11 @@ describe('VaultInternal', () => { const runP = runGen(writeGen); await sleep(waitDelay); expect(finished).toBe(false); - releaseWrite(); + await releaseWrite(); await runP; expect(finished).toBe(true); - const releaseRead = await lock.acquireRead(); + const [releaseRead] = await lock.read()(); finished = false; const writeGen2 = vault.writeG(async function* () { yield; @@ -785,7 +788,7 @@ describe('VaultInternal', () => { }); const runP2 = runGen(writeGen2); await sleep(waitDelay); - releaseRead(); + await releaseRead(); await runP2; expect(finished).toBe(true); }); @@ -793,7 +796,7 @@ describe('VaultInternal', () => { // @ts-ignore: kidnap lock const lock = vault.lock; // Hold a write lock - const releaseWrite = await lock.acquireWrite(); + const [releaseWrite] = await lock.write()(); let finished = false; const writeP = vault.readF(async () => { @@ -801,7 +804,7 @@ describe('VaultInternal', () => { }); await sleep(waitDelay); expect(finished).toBe(false); - releaseWrite(); + await releaseWrite(); await writeP; expect(finished).toBe(true); }); @@ -809,7 +812,7 @@ describe('VaultInternal', () => { // @ts-ignore: kidnap lock const lock = vault.lock; // Hold a write lock - const releaseWrite = await lock.acquireWrite(); + const [releaseWrite] = await lock.write()(); let finished = false; const writeGen = vault.readG(async function* () { yield; @@ -819,7 +822,7 @@ describe('VaultInternal', () => { const runP = runGen(writeGen); await sleep(waitDelay); expect(finished).toBe(false); - releaseWrite(); + await releaseWrite(); await runP; expect(finished).toBe(true); }); @@ -827,7 +830,7 @@ describe('VaultInternal', () => { // @ts-ignore: kidnap lock const lock = vault.lock; // Hold a write lock - const releaseRead = await lock.acquireRead(); + const [releaseRead] = await lock.read()(); const finished: boolean[] = []; const doThing = async () => { finished.push(true); @@ -839,13 +842,13 @@ describe('VaultInternal', () => { vault.readF(doThing), ]); expect(finished.length).toBe(4); - releaseRead(); + await releaseRead(); }); test('readG allows concurrent reads', async () => { // @ts-ignore: kidnap lock const lock = vault.lock; // Hold a write lock - const releaseRead = await lock.acquireRead(); + const [releaseRead] = await lock.read()(); const finished: boolean[] = []; const doThing = async function* () { yield; @@ -859,7 +862,7 @@ describe('VaultInternal', () => { runGen(vault.readG(doThing)), ]); expect(finished.length).toBe(4); - releaseRead(); + await releaseRead(); }); // Life-cycle test('can create with CreateVaultInternal', async () => { @@ -871,8 +874,7 @@ describe('VaultInternal', () => { efs, keyManager: fakeKeyManager, vaultId: vaultId1, - vaultsDb, - vaultsDbDomain, + vaultsDbPath, logger, }); // Data exists for vault now @@ -894,8 +896,7 @@ describe('VaultInternal', () => { efs, keyManager: fakeKeyManager, vaultId: vaultId1, - vaultsDb, - vaultsDbDomain, + vaultsDbPath, logger, }); // Data exists for vault now @@ -914,8 +915,7 @@ describe('VaultInternal', () => { efs, keyManager: fakeKeyManager, vaultId: vaultId1, - vaultsDb, - vaultsDbDomain, + vaultsDbPath, logger, }); diff --git a/tests/vaults/VaultManager.test.ts b/tests/vaults/VaultManager.test.ts index 2117ea7a8..9c7bc4021 100644 --- a/tests/vaults/VaultManager.test.ts +++ b/tests/vaults/VaultManager.test.ts @@ -30,6 +30,7 @@ import * as keysUtils from '@/keys/utils'; import { sleep } from '@/utils'; import VaultInternal from '@/vaults/VaultInternal'; import * as testsUtils from '../utils'; +import { expectRemoteError } from '../utils'; const mockedGenerateDeterministicKeyPair = jest .spyOn(keysUtils, 'generateDeterministicKeyPair') @@ -139,44 +140,50 @@ describe('VaultManager', () => { await vaultManager?.destroy(); } }); - test('can create many vaults and open a vault', async () => { - const vaultManager = await VaultManager.createVaultManager({ - vaultsPath, - keyManager: dummyKeyManager, - gestaltGraph: {} as GestaltGraph, - nodeConnectionManager: {} as NodeConnectionManager, - acl: {} as ACL, - notificationsManager: {} as NotificationsManager, - db, - logger: logger.getChild(VaultManager.name), - }); - try { - const vaultNames = [ - 'Vault1', - 'Vault2', - 'Vault3', - 'Vault4', - 'Vault5', - 'Vault6', - 'Vault7', - 'Vault8', - 'Vault9', - 'Vault10', - 'Vault11', - 'Vault12', - 'Vault13', - 'Vault14', - 'Vault15', - ]; - for (const vaultName of vaultNames) { - await vaultManager.createVault(vaultName as VaultName); + test( + 'can create many vaults and open a vault', + async () => { + const vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + keyManager: dummyKeyManager, + gestaltGraph: {} as GestaltGraph, + nodeConnectionManager: {} as NodeConnectionManager, + acl: {} as ACL, + notificationsManager: {} as NotificationsManager, + db, + logger: logger.getChild(VaultManager.name), + }); + try { + const vaultNames = [ + 'Vault1', + 'Vault2', + 'Vault3', + 'Vault4', + 'Vault5', + 'Vault6', + 'Vault7', + 'Vault8', + 'Vault9', + 'Vault10', + 'Vault11', + 'Vault12', + 'Vault13', + 'Vault14', + 'Vault15', + ]; + for (const vaultName of vaultNames) { + await vaultManager.createVault(vaultName as VaultName); + } + expect((await vaultManager.listVaults()).size).toEqual( + vaultNames.length, + ); + } finally { + await vaultManager?.stop(); + await vaultManager?.destroy(); } - expect((await vaultManager.listVaults()).size).toEqual(vaultNames.length); - } finally { - await vaultManager?.stop(); - await vaultManager?.destroy(); - } - }); + }, + global.defaultTimeout * 2, + ); test('can rename a vault', async () => { const vaultManager = await VaultManager.createVaultManager({ vaultsPath, @@ -730,12 +737,13 @@ describe('VaultManager', () => { 'pull', ); - await expect(() => + await expectRemoteError( vaultManager.cloneVault( remoteKeynode1Id, 'not-existing' as VaultName, ), - ).rejects.toThrow(vaultsErrors.ErrorVaultsVaultUndefined); + vaultsErrors.ErrorVaultsVaultUndefined, + ); } finally { await vaultManager?.stop(); await vaultManager?.destroy(); @@ -818,9 +826,10 @@ describe('VaultManager', () => { }); try { // Should reject with no permissions set - await expect(() => + await expectRemoteError( vaultManager.cloneVault(remoteKeynode1Id, remoteVaultId), - ).rejects.toThrow(vaultsErrors.ErrorVaultsPermissionDenied); + vaultsErrors.ErrorVaultsPermissionDenied, + ); // No new vault created expect((await vaultManager.listVaults()).size).toBe(0); } finally { @@ -1302,7 +1311,7 @@ describe('VaultManager', () => { const vaultsMap = vaultManager.vaultMap; const vaultAndLock = vaultsMap.get(vaultId.toString() as VaultIdString); const lock = vaultAndLock!.lock; - const releaseWrite = await lock.acquireWrite(); + const [releaseWrite] = await lock.write()(); // Pulling vault respects VaultManager write lock const pullP = vaultManager.pullVault({ @@ -1329,7 +1338,7 @@ describe('VaultManager', () => { const vault = vaultAndLock!.vault!; // @ts-ignore: kidnap vault lock const vaultLock = vault.lock; - const releaseVaultWrite = await vaultLock.acquireWrite(); + const [releaseVaultWrite] = await vaultLock.write()(); // Pulling vault respects VaultManager write lock gitPullMock.mockClear(); const pullP2 = vaultManager.pullVault({ @@ -1513,18 +1522,21 @@ describe('VaultManager', () => { // Scanning vaults // Should throw due to no permission - await expect(async () => { + const testFun = async () => { for await (const _ of vaultManager.scanVaults(targetNodeId)) { // Should throw } - }).rejects.toThrow(vaultsErrors.ErrorVaultsPermissionDenied); + }; + await expectRemoteError( + testFun(), + vaultsErrors.ErrorVaultsPermissionDenied, + ); // Should throw due to lack of scan permission await remoteAgent.gestaltGraph.setGestaltActionByNode(nodeId1, 'notify'); - await expect(async () => { - for await (const _ of vaultManager.scanVaults(targetNodeId)) { - // Should throw - } - }).rejects.toThrow(vaultsErrors.ErrorVaultsPermissionDenied); + await expectRemoteError( + testFun(), + vaultsErrors.ErrorVaultsPermissionDenied, + ); // Setting permissions await remoteAgent.gestaltGraph.setGestaltActionByNode(nodeId1, 'scan'); @@ -1586,7 +1598,7 @@ describe('VaultManager', () => { const vaultAndLock = vaultMap.get(vaultId.toString() as VaultIdString)!; const lock = vaultAndLock.lock; const vault = vaultAndLock.vault!; - const release = await lock.acquireWrite(); + const [release] = await lock.write()(); // Try to destroy const closeP = vaultManager.closeVault(vaultId); await sleep(1000); @@ -1596,7 +1608,7 @@ describe('VaultManager', () => { vaultMap.get(vaultId.toString() as VaultIdString)!.vault, ).toBeDefined(); // Release the lock - release(); + await release(); await closeP; expect(vault[running]).toBe(false); expect(vaultMap.get(vaultId.toString() as VaultIdString)).toBeUndefined(); @@ -1625,7 +1637,7 @@ describe('VaultManager', () => { const vaultAndLock = vaultMap.get(vaultId.toString() as VaultIdString)!; const lock = vaultAndLock.lock; const vault = vaultAndLock.vault!; - const release = await lock.acquireWrite(); + const [release] = await lock.write()(); // Try to destroy const destroyP = vaultManager.destroyVault(vaultId); await sleep(1000); @@ -1635,7 +1647,7 @@ describe('VaultManager', () => { vaultMap.get(vaultId.toString() as VaultIdString)!.vault, ).toBeDefined(); // Release the lock - release(); + await release(); await destroyP; expect(vault[destroyed]).toBe(true); expect(vaultMap.get(vaultId.toString() as VaultIdString)).toBeUndefined(); @@ -1663,7 +1675,7 @@ describe('VaultManager', () => { // Getting and holding the lock const vaultAndLock = vaultMap.get(vaultId.toString() as VaultIdString)!; const lock = vaultAndLock.lock; - const release = await lock.acquireWrite(); + const [release] = await lock.write()(); // Try to use vault let finished = false; const withP = vaultManager.withVaults([vaultId], async () => { @@ -1673,7 +1685,7 @@ describe('VaultManager', () => { // Shouldn't be destroyed expect(finished).toBe(false); // Release the lock - release(); + await release(); await withP; expect(finished).toBe(true); } finally { @@ -1713,6 +1725,7 @@ describe('VaultManager', () => { db, logger: logger.getChild(VaultManager.name), }); + try { await expect( Promise.all([ @@ -1834,8 +1847,7 @@ describe('VaultManager', () => { await vaultManager.stop(); await vaultManager.destroy(); // Vaults DB should be empty - const vaultsDb = await db.level(VaultManager.constructor.name); - expect(await db.count(vaultsDb)).toBe(0); + expect(await db.count([VaultManager.constructor.name])).toBe(0); vaultManager2 = await VaultManager.createVaultManager({ vaultsPath, keyManager: dummyKeyManager, diff --git a/tests/vaults/VaultOps.test.ts b/tests/vaults/VaultOps.test.ts index e376eb306..81e061cd3 100644 --- a/tests/vaults/VaultOps.test.ts +++ b/tests/vaults/VaultOps.test.ts @@ -1,7 +1,7 @@ import type { VaultId } from '@/vaults/types'; import type { Vault } from '@/vaults/Vault'; import type KeyManager from '@/keys/KeyManager'; -import type { DBDomain, DBLevel } from '@matrixai/db'; +import type { LevelPath } from '@matrixai/db'; import fs from 'fs'; import path from 'path'; import os from 'os'; @@ -24,8 +24,7 @@ describe('VaultOps', () => { let vaultInternal: VaultInternal; let vault: Vault; let db: DB; - let vaultsDb: DBLevel; - let vaultsDbDomain: DBDomain; + let vaultsDbPath: LevelPath; const dummyKeyManager = { getNodeId: () => { return testUtils.generateRandomNodeId(); @@ -64,8 +63,7 @@ describe('VaultOps', () => { }, ); db = await DB.createDB({ dbPath: path.join(dataDir, 'db'), logger }); - vaultsDbDomain = ['vaults']; - vaultsDb = await db.level(vaultsDbDomain[0]); + vaultsDbPath = ['vaults']; vaultInternal = await VaultInternal.createVaultInternal({ keyManager: dummyKeyManager, vaultId, @@ -73,8 +71,7 @@ describe('VaultOps', () => { logger: logger.getChild(VaultInternal.name), fresh: true, db, - vaultsDbDomain, - vaultsDb, + vaultsDbPath: vaultsDbPath, vaultName: 'VaultName', }); vault = vaultInternal as Vault; diff --git a/tsconfig.json b/tsconfig.json index d4abc0d16..8ee4055cd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,8 @@ { "compilerOptions": { "outDir": "./dist", + "tsBuildInfoFile": "./dist/tsbuildinfo", + "incremental": true, "sourceMap": true, "declaration": true, "allowJs": true, @@ -12,7 +14,7 @@ "resolveJsonModule": true, "moduleResolution": "node", "module": "CommonJS", - "target": "ES2020", + "target": "ES2021", "baseUrl": "./src", "paths": { "@": ["index"], diff --git a/utils.nix b/utils.nix index fe376455a..e63e463df 100644 --- a/utils.nix +++ b/utils.nix @@ -6,6 +6,7 @@ , pkgs , lib , fetchurl +, fetchFromGitHub }: rec { @@ -13,9 +14,17 @@ rec { basename = builtins.baseNameOf node2nixDev.packageName; src = nix-gitignore.gitignoreSource [".git"] ./.; nodeVersion = builtins.elemAt (lib.versions.splitVersion nodejs.version) 0; + # custom node2nix directly from GitHub + node2nixSrc = fetchFromGitHub { + owner = "svanderburg"; + repo = "node2nix"; + rev = "68f5735f9a56737e3fedceb182705985e3ab8799"; + sha256 = "1f791vikig65ly5vcw6zjd0nv2qb8l5w5lr3xy343iq6746s1bil"; + }; + node2nix = (import "${node2nixSrc}/release.nix" {}).package.x86_64-linux; node2nixDrv = dev: runCommandNoCC "node2nix" {} '' mkdir $out - ${nodePackages.node2nix}/bin/node2nix \ + ${node2nix}/bin/node2nix \ ${lib.optionalString dev "--development"} \ --input ${src}/package.json \ --lock ${src}/package-lock.json \ @@ -36,35 +45,30 @@ rec { buildInputs = attrs.buildInputs ++ [ nodePackages.node-gyp-build ]; dontNpmInstall = true; postInstall = '' - # The dependencies were prepared in the install phase - # See `node2nix` generated `node-env.nix` for details. + # The dependencies were prepared in the installphase + # See `node2nix` generated `node-env.nix` for details npm run build - - # This call does not actually install packages. The dependencies - # are present in `node_modules` already. It creates symlinks in - # $out/lib/node_modules/.bin according to `bin` section in `package.json`. - npm install ''; }); pkgBuilds = { - "3.1" = { + "3.3" = { "linux-x64" = fetchurl { - url = "https://github.com/vercel/pkg-fetch/releases/download/v3.1/node-v14.17.0-linux-x64"; - sha256 = "11vk7vfxa1327mr71gys8fhglrpscjaxrpnbk1jbnj5llyzcx52l"; + url = "https://github.com/vercel/pkg-fetch/releases/download/v3.3/node-v16.14.2-linux-x64"; + sha256 = "1g5sljbb7zqqbfvl3n1hzfy6fd97ch06bbjfxnd7bz6ncmjk3rcg"; }; "win32-x64" = fetchurl { - url = "https://github.com/vercel/pkg-fetch/releases/download/v3.1/node-v14.17.0-win-x64"; - sha256 = "08wf9ldy33sac1vmhd575zf2fhrbci3wz88a9nwdbccsxrkbgklc"; + url = "https://github.com/vercel/pkg-fetch/releases/download/v3.3/node-v16.14.2-win-x64"; + sha256 = "1c1fr8fvrfm49qgn0dibbr5givz2qccb91qrwilxlhj289ba0sgm"; }; "macos-x64" = fetchurl { - url = "https://github.com/vercel/pkg-fetch/releases/download/v3.1/node-v14.17.0-macos-x64"; - sha256 = "0lwa6s66wy7qmj4wbpa65hv996vxzznrscqgwrk3q2zzpsra24q7"; + url = "https://github.com/vercel/pkg-fetch/releases/download/v3.3/node-v16.14.2-macos-x64"; + sha256 = "1hq7v40vzc2bfr29y71lm0snaxcc8rys5w0da7pi5nmx4pyybc2v"; }; }; }; pkgCachePath = let - pkgBuild = pkgBuilds."3.1"; + pkgBuild = pkgBuilds."3.3"; fetchedName = n: builtins.replaceStrings ["node"] ["fetched"] n; in linkFarm "pkg-cache" @@ -82,7 +86,7 @@ rec { path = pkgBuild.macos-x64; } ]; - pkg = pkgs.nodePackages.pkg.override { + pkg = nodePackages.pkg.override { postFixup = '' patch -p0 < ${./nix/leveldown.patch} '';