From 08f7886c3fbc7bb523d91800e7810a2bdb660758 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 28 Mar 2022 16:04:42 +1100 Subject: [PATCH 01/74] fix: adding dependencies for `async-locks`, `db`, `resources` and `errors` Updating dependencies to bring in new libraries such as locks, resources and errors. Some domains have been updated to use this change. --- package-lock.json | 229 +++++++++------------------ package.json | 7 +- src/acl/ACL.ts | 157 +++++++++--------- src/locks/Locks.ts | 111 +++++++++++++ src/locks/index.ts | 1 + src/nodes/NodeConnectionManager.ts | 13 +- src/schema/Schema.ts | 16 +- src/types.ts | 6 + src/utils/context.ts | 75 --------- src/utils/index.ts | 2 - src/utils/locks.ts | 85 ---------- src/vaults/VaultInternal.ts | 8 +- src/vaults/VaultManager.ts | 23 ++- tests/utils.test.ts | 245 ----------------------------- 14 files changed, 304 insertions(+), 674 deletions(-) create mode 100644 src/locks/Locks.ts create mode 100644 src/locks/index.ts delete mode 100644 src/utils/context.ts delete mode 100644 src/utils/locks.ts diff --git a/package-lock.json b/package-lock.json index aad840c5a..be41f04fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1592,34 +1592,49 @@ } } }, + "@matrixai/async-locks": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.0.0.tgz", + "integrity": "sha512-wpU6L5o/0BhBsjYt4BH2J3L0+yDhxotCi6cRF7QZbm03u/tdq8tgwyOzXe+MPArh+EZhsBrnBOCdUpUhgZNRZQ==", + "requires": { + "@matrixai/resources": "^1.0.0", + "async-mutex": "^0.3.2", + "ts-custom-error": "^3.2.0" + } + }, "@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==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.2.0.tgz", + "integrity": "sha512-JfcpZ8zbNgdQK3mpHQisCY6TKGUO5+Issh5KDvR3zBtfdSKHJLgrqweDIyLtM9D0RT5jO5HOY+lthI/8Yfi/PA==", "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", + "@matrixai/errors": "^1.0.1", + "@matrixai/logger": "^2.1.0", + "@matrixai/resources": "^1.0.0", + "@matrixai/workers": "^1.2.5", + "@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", - "ts-custom-error": "^3.2.0" + "threads": "^1.6.5" }, "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==", + "@matrixai/errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", + "integrity": "sha512-9NbIm3rPMkZz+Ma5tfKduVCWfvYzdHlO89u9mBap7FzJqXkl4yoENjMZm5Do6PvhtIYtRcm6+eTgWvHd6pkdGg==", "requires": { - "tslib": "^2.3.1" + "ts-custom-error": "^3.2.0" } } } }, + "@matrixai/errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", + "integrity": "sha512-9NbIm3rPMkZz+Ma5tfKduVCWfvYzdHlO89u9mBap7FzJqXkl4yoENjMZm5Do6PvhtIYtRcm6+eTgWvHd6pkdGg==", + "requires": { + "ts-custom-error": "^3.2.0" + } + }, "@matrixai/id": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/@matrixai/id/-/id-3.3.2.tgz", @@ -1634,6 +1649,11 @@ "resolved": "https://registry.npmjs.org/@matrixai/logger/-/logger-2.1.0.tgz", "integrity": "sha512-UmLuXi2PJ03v0Scfl57217RPnjEZDRLlpfdIjIwCfju+kofnhhCI9P7OZu3/FgW147vbvSzWCrrtpwJiLROUUA==" }, + "@matrixai/resources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@matrixai/resources/-/resources-1.0.0.tgz", + "integrity": "sha512-B1ZkySZwOZTIzhK+YTN4HifOTd1dk1ifDUV8/8WgGho2nUZzIMYms7iDmW/ZHUCkqvWupKY6AYvfwnKBOJJnWg==" + }, "@matrixai/workers": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.2.5.tgz", @@ -1718,6 +1738,11 @@ "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", @@ -2698,12 +2723,9 @@ } }, "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", @@ -3352,6 +3374,26 @@ "threads": "^1.6.5", "ts-custom-error": "^3.2.0", "util-callbackify": "^1.0.0" + }, + "dependencies": { + "@matrixai/db": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-1.2.1.tgz", + "integrity": "sha512-1W8TORmRX3q3NugZFn0FTgI0mo/n0nWBTXHKXwwPfxtdyNfi18JCj3HVCwWdToOo87ypnS/mqLDIUTSHbF7F3Q==", + "requires": { + "@matrixai/async-init": "^1.6.0", + "@matrixai/logger": "^2.1.0", + "@matrixai/workers": "^1.2.5", + "abstract-leveldown": "^7.2.0", + "async-mutex": "^0.3.1", + "level": "7.0.1", + "levelup": "^5.1.1", + "sublevel-prefixer": "^1.0.0", + "subleveldown": "^6.0.1", + "threads": "^1.6.5", + "ts-custom-error": "^3.2.0" + } + } } }, "end-of-stream": { @@ -4805,11 +4847,6 @@ "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==" - }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -6510,9 +6547,9 @@ "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", @@ -7650,11 +7687,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", @@ -8644,124 +8676,16 @@ "integrity": "sha1-TuRZ72Y6yFvyj8ZJ17eWX9ppEHM=" }, "subleveldown": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/subleveldown/-/subleveldown-5.0.1.tgz", - "integrity": "sha512-cVqd/URpp7si1HWu5YqQ3vqQkjuolAwHypY1B4itPlS71/lsf6TQPZ2Y0ijT22EYVkvH5ove9JFJf4u7VGPuZw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/subleveldown/-/subleveldown-6.0.1.tgz", + "integrity": "sha512-Cnf+cn2wISXU2xflY1SFIqfX4hG2d6lFk2P5F8RDQLmiqN9Ir4ExNfUFH6xnmizMseM/t+nMsDUKjN9Kw6ShFA==", "requires": { - "abstract-leveldown": "^6.3.0", - "encoding-down": "^6.2.0", + "abstract-leveldown": "^7.2.0", + "encoding-down": "^7.1.0", "inherits": "^2.0.3", "level-option-wrap": "^1.1.0", - "levelup": "^4.4.0", + "levelup": "^5.1.1", "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": { @@ -9619,11 +9543,6 @@ "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", diff --git a/package.json b/package.json index 9f6833c3d..1f45d3202 100644 --- a/package.json +++ b/package.json @@ -74,12 +74,14 @@ "dependencies": { "@grpc/grpc-js": "1.3.7", "@matrixai/async-init": "^1.6.0", - "@matrixai/db": "^1.1.5", + "@matrixai/async-locks": "^2.0.0", + "@matrixai/db": "^3.2.0", + "@matrixai/errors": "^1.0.1", "@matrixai/id": "^3.3.2", "@matrixai/logger": "^2.1.0", + "@matrixai/resources": "^1.0.0", "@matrixai/workers": "^1.2.5", "ajv": "^7.0.4", - "async-mutex": "^0.3.2", "bip39": "^3.0.3", "canonicalize": "^1.0.5", "cheerio": "^1.0.0-rc.5", @@ -103,7 +105,6 @@ "resource-counter": "^1.2.4", "rimraf": "^3.0.2", "threads": "^1.6.5", - "ts-custom-error": "^3.2.0", "utp-native": "^2.5.3", "uuid": "^8.3.0" }, diff --git a/src/acl/ACL.ts b/src/acl/ACL.ts index 358663d51..2bff1d5f9 100644 --- a/src/acl/ACL.ts +++ b/src/acl/ACL.ts @@ -1,23 +1,32 @@ +import type { + DB, + DBTransaction, + KeyPath, + LevelPath +} from '@matrixai/db'; import type { PermissionId, PermissionIdString, Permission, VaultActions, } from './types'; -import type { DB, DBLevel, DBOp } from '@matrixai/db'; +import type { Locks } from '../locks'; 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 { RWLockWriter } from '@matrixai/async-locks'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import * as aclUtils from './utils'; import * as aclErrors from './errors'; +import { utils as dbUtils } from '@matrixai/db'; +import { withF } from '@matrixai/resources'; interface ACL extends CreateDestroyStartStop {} @CreateDestroyStartStop( @@ -27,15 +36,17 @@ interface ACL extends CreateDestroyStartStop {} class ACL { static async createACL({ db, + locks, logger = new Logger(this.name), fresh = false, }: { db: DB; + locks: Locks; logger?: Logger; fresh?: boolean; }): Promise { logger.info(`Creating ${this.name}`); - const acl = new ACL({ db, logger }); + const acl = new ACL({ db, locks, logger }); await acl.start({ fresh }); logger.info(`Created ${this.name}`); return acl; @@ -43,24 +54,55 @@ 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 locks: Locks; + + 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']; + + // lock across the usages of the DB + // it makes sense to use + // Symbol.for("key") + // symbol for is found in teh global registry, if it doesn't exist, it is added to the global registry and returned + // we can identify our locks by this + // to do this, we should have a global lock system in case we want to LOCK across multiple domains + // then other domains can also ensure those locks are being done as well + // and it is a like a PATH for a specific domain + // we can pass a keyPath + // and we can lock a level path + // well right now it can only be a keypath + // this.acquireLock(key: Buffer) + // and we identify our key buffer into a collection + // we can do a collection struce + // the symbols don't quite make sense, since we cannot attach a lock there anyway + // so we have to do this as well + // if it is not the DB problem we can just do this + // this.acquireLock() + + // KeyPath | string | Buffer + // locking an entire level is an interesting idea + // then you could have a very specific locking system + // No more single mutex + // protected lock: Mutex = new Mutex(); + protected generatePermId: () => PermissionId; - constructor({ db, logger }: { db: DB; logger: Logger }) { + constructor({ db, locks, logger }: { db: DB; locks: Locks; logger: Logger }) { this.logger = logger; this.db = db; - } - - get locked(): boolean { - return this.lock.isLocked(); + this.locks = locks; } public async start({ @@ -69,22 +111,9 @@ class ACL { 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,60 +125,36 @@ 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); - } - } - @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, - ); - const permId2 = await this.db.get( - this.aclNodesDbDomain, - nodeId2.toBuffer(), - true, + const nodeId1Path = [...this.aclNodesDbPath, nodeId1.toBuffer()] as unknown as KeyPath; + const nodeId2Path = [...this.aclNodesDbPath, nodeId2.toBuffer()] as unknown as KeyPath; + if (tran == null) { + return withF( + [ + this.db.transaction(), + this.locks.lockRead( + dbUtils.keyPathToKey(nodeId1Path).toString('binary'), + dbUtils.keyPathToKey(nodeId2Path).toString('binary') + ), + ], + async ([tran]) => this.sameNodePerm(nodeId1, nodeId2, tran) ); - if (permId1 != null && permId2 != null && permId1 === permId2) { - return true; - } - return false; - }); + } + const permId1 = await tran.get(nodeId1Path, true); + const permId2 = await tran.get(nodeId2Path, true); + if (permId1 != null && permId2 != null) { + return IdInternal.fromBuffer(permId1).equals(IdInternal.fromBuffer(permId2)); + } + return false; } @ready(new aclErrors.ErrorACLNotRunning()) diff --git a/src/locks/Locks.ts b/src/locks/Locks.ts new file mode 100644 index 000000000..a91ad1807 --- /dev/null +++ b/src/locks/Locks.ts @@ -0,0 +1,111 @@ +import type { ResourceAcquire, ResourceRelease } from '@matrixai/resources'; +import type { NonEmptyArray } from '@/types'; +import { RWLockWriter } from '@matrixai/async-locks'; + +/** + * Generic dynamic read-write lock collection + * This enables advisory-locking across all domains + */ +class Locks { + protected _locks: Map; + + get locks(): ReadonlyMap { + return this._locks; + } + + /** + * Read-lock a sequence of ids + * The ids will be sorted before locking to ensure lock-hierarchy + * in order to prevent deadlocks + */ + public lockRead(...ids: NonEmptyArray): ResourceAcquire> { + return async () => { + ids.sort(); + const locks: Array<[string, ResourceRelease, RWLockWriter]> = []; + for (const id of ids) { + let lock = this._locks.get(id); + if (lock == null) { + lock = new RWLockWriter(); + this._locks.set(id, lock); + } + let lockRelease: ResourceRelease; + try { + [lockRelease] = await lock.acquireRead(); + } catch (e) { + // Release all intermediate locks in reverse order + locks.reverse(); + for (const [id, lockRelease, lock] of locks) { + await lockRelease(); + if (!lock!.isLocked()) { + this._locks.delete(id); + } + } + throw e; + } + locks.push([id, lockRelease, lock]); + } + return [ + async () => { + // Release all locks in reverse order + locks.reverse(); + for (const [id, lockRelease, lock] of locks) { + await lockRelease(); + if (!lock!.isLocked()) { + this._locks.delete(id); + } + } + }, + locks.map(([,,lock]) => lock) as NonEmptyArray + ]; + }; + } + + /** + * Write-lock a sequence of ids + * The ids will be sorted before locking to ensure lock-hierarchy + * in order to prevent deadlocks + */ + public lockWrite(...ids: NonEmptyArray): ResourceAcquire> { + return async () => { + ids.sort(); + const locks: Array<[string, ResourceRelease, RWLockWriter]> = []; + for (const id of ids) { + let lock = this._locks.get(id); + if (lock == null) { + lock = new RWLockWriter(); + this._locks.set(id, lock); + } + let lockRelease: ResourceRelease; + try { + [lockRelease] = await lock.acquireWrite(); + } catch (e) { + // Release all intermediate locks in reverse order + locks.reverse(); + for (const [id, lockRelease, lock] of locks) { + await lockRelease(); + if (!lock!.isLocked()) { + this._locks.delete(id); + } + } + throw e; + } + locks.push([id, lockRelease, lock]); + } + return [ + async () => { + // Release all locks in reverse order + locks.reverse(); + for (const [id, lockRelease, lock] of locks) { + await lockRelease(); + if (!lock!.isLocked()) { + this._locks.delete(id); + } + } + }, + locks.map(([,,lock]) => lock) as NonEmptyArray + ]; + }; + } +} + +export default Locks; diff --git a/src/locks/index.ts b/src/locks/index.ts new file mode 100644 index 000000000..fe97431ee --- /dev/null +++ b/src/locks/index.ts @@ -0,0 +1 @@ +export { default as Locks } from './Locks'; diff --git a/src/nodes/NodeConnectionManager.ts b/src/nodes/NodeConnectionManager.ts index 6160aa60a..5338e0058 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 { @@ -24,12 +24,13 @@ 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'; +import { withF } from '@matrixai/resources'; +import { RWLockWriter } from '@matrixai/async-locks'; type ConnectionAndLock = { connection?: NodeConnection; timer?: NodeJS.Timer; - lock: RWLock; + lock: RWLockWriter; }; interface NodeConnectionManager extends StartStop {} @@ -231,7 +232,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, ); @@ -260,7 +261,7 @@ class NodeConnectionManager { return await this.establishNodeConnection(targetNodeId, lock); }); } else { - lock = new RWLock(); + lock = new RWLockWriter(); connAndLock = { lock }; this.connections.set( targetNodeId.toString() as NodeIdString, @@ -290,7 +291,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 diff --git a/src/schema/Schema.ts b/src/schema/Schema.ts index 546d81956..33c50fa45 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; } @@ -142,7 +136,7 @@ class Schema { } 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( @@ -169,7 +163,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, @@ -191,7 +185,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/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/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/vaults/VaultInternal.ts b/src/vaults/VaultInternal.ts index 63611b1a8..76f87e13b 100644 --- a/src/vaults/VaultInternal.ts +++ b/src/vaults/VaultInternal.ts @@ -1,6 +1,7 @@ import type { ReadCommitResult } from 'isomorphic-git'; import type { EncryptedFS } from 'encryptedfs'; import type { DB, DBDomain, DBLevel } from '@matrixai/db'; +import type { ResourceAcquire } from '@matrixai/resources'; import type { CommitId, CommitLog, @@ -15,7 +16,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 +26,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'; @@ -190,7 +190,7 @@ class VaultInternal { protected vaultsNamesDomain: DBDomain; protected efs: EncryptedFS; protected efsVault: EncryptedFS; - protected lock: RWLock = new RWLock(); + protected lock: RWLockWriter = new RWLockWriter(); public readLock: ResourceAcquire = async () => { const release = await this.lock.acquireRead(); diff --git a/src/vaults/VaultManager.ts b/src/vaults/VaultManager.ts index ed65478f5..71699d1ae 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 { ResourceAcquire } 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; } >; @@ -125,7 +124,7 @@ class VaultManager { protected vaultsDb: DBLevel; protected vaultsNamesDbDomain: DBDomain = [...this.vaultsDbDomain, 'names']; protected vaultsNamesDb: DBLevel; - protected vaultsNamesLock: RWLock = new RWLock(); + protected vaultsNamesLock: RWLockWriter = new RWLockWriter(); // VaultId -> VaultMetadata protected vaultMap: VaultMap = new Map(); protected vaultKey: Buffer; @@ -261,11 +260,11 @@ class VaultManager { this.efs.unsetWorkerManager(); } - protected getLock(vaultId: VaultId): RWLock { + protected getLock(vaultId: VaultId): RWLockWriter { 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; } @@ -314,7 +313,7 @@ class VaultManager { true, ); }); - const lock = new RWLock(); + const lock = new RWLockWriter(); const vaultIdString = vaultId.toString() as VaultIdString; this.vaultMap.set(vaultIdString, { lock }); return await withF([this.getWriteLock(vaultId)], async () => { @@ -556,7 +555,7 @@ class VaultManager { vaultNameOrId: VaultId | VaultName, ): Promise { 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( @@ -802,7 +801,7 @@ class VaultManager { @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) protected async getVault(vaultId: VaultId): Promise { 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) { @@ -842,7 +841,7 @@ class VaultManager { } } else { // Neither vault nor lock exists - lock = new RWLock(); + lock = new RWLockWriter(); vaultAndLock = { lock }; this.vaultMap.set(vaultIdString, vaultAndLock); let release; 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]); - }); }); From feb107261bcc70e95b0fb69eac4b6897bc827020 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 26 Apr 2022 12:03:46 +1000 Subject: [PATCH 02/74] build: upgrade to Node v16 Updated pkgs.nix to a5774e76bb8c3145eac524be62375c937143b80c Updated node2nix to 1.11.0 and loading directly from GitHub Updated pkg to 5.6.0 and using pkg-fetch 3.3 base binaries Updated to TypeScript 4.5+ Updated @types/node to 16.11.7 Updated node-gyp-build to 4.4.0 Updated typedoc to 0.22.15, the .nojekyll generation is automatic Changed to target ES2021 as node 16 supports it Bin executable duct-tape in default.nix because node2nix no longer generates bin executables Updated pkg builds hashes to v16.14.2 and specified target node range --- .eslintrc | 2 +- default.nix | 25 +- package-lock.json | 12931 +++++++++++++++++++++++++++++++++++++++++++- package.json | 12 +- pkgs.nix | 4 +- release.nix | 6 +- shell.nix | 2 +- tsconfig.json | 2 +- utils.nix | 38 +- 9 files changed, 12819 insertions(+), 203 deletions(-) diff --git a/.eslintrc b/.eslintrc index f66c592e8..d53f180f4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -20,7 +20,7 @@ "parserOptions": { "project": "tsconfig.json", "sourceType": "module", - "ecmaVersion": 2020 + "ecmaVersion": 2021 }, "rules": { "linebreak-style": ["error", "unix"], diff --git a/default.nix b/default.nix index 509b730c7..afc0a37fe 100644 --- a/default.nix +++ b/default.nix @@ -1,5 +1,6 @@ { runCommandNoCC , callPackage +, jq }: let @@ -32,11 +33,25 @@ let "${utils.node2nixProd}/lib/node_modules" \ "$out/lib/node_modules/$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/package-lock.json b/package-lock.json index be41f04fe..d7ad332ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,12606 @@ { "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.3.7", + "@matrixai/async-init": "^1.6.0", + "@matrixai/async-locks": "^2.0.0", + "@matrixai/db": "^3.2.0", + "@matrixai/errors": "^1.0.1", + "@matrixai/id": "^3.3.2", + "@matrixai/logger": "^2.1.0", + "@matrixai/resources": "^1.0.0", + "@matrixai/workers": "^1.2.5", + "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.4.3", + "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": "^26.0.20", + "@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.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", + "grpc_tools_node_protoc_ts": "^5.1.3", + "jest": "^26.6.3", + "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.2.1", + "ts-jest": "^26.4.4", + "ts-node": "^10.4.0", + "tsconfig-paths": "^3.9.0", + "typedoc": "^0.22.15", + "typescript": "^4.5.2", + "typescript-cached-transpile": "0.0.6" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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, + "dependencies": { + "@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", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "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.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==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "regexpu-core": "^4.7.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-wrap-function": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", + "@babel/plugin-proposal-optional-chaining": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.15.4", + "@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.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==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@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.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@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.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@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.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", + "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@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.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@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.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@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.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", + "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@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.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==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@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.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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@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.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==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@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/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.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==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "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-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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "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-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==", + "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-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, + "dependencies": { + "@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", + "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.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==", + "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-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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "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-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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "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.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==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.15.4", + "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.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", + "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", + "dev": true, + "dependencies": { + "@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-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.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==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "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-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==", + "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-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==", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.14.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "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-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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "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-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==", + "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-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==", + "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-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==", + "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-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==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@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", + "@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.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", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "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.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime/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/@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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, + "dependencies": { + "@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", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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/@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/@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "dependencies": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" + } + }, + "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": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.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/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@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/@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==", + "dependencies": { + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@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==", + "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": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "dependencies": { + "@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", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "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", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "dev": true, + "dependencies": { + "@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", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "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", + "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" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "node-notifier": "^8.0.0" + } + }, + "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/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/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==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/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, + "dependencies": { + "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" + } + }, + "node_modules/@jest/reporters/node_modules/node-notifier/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, + "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/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/@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": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/source-map/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/@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==", + "dev": true, + "dependencies": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "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", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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/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/@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": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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/@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==", + "dependencies": { + "async-mutex": "^0.3.2", + "ts-custom-error": "^3.2.0" + } + }, + "node_modules/@matrixai/async-init/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/@matrixai/async-locks": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.0.0.tgz", + "integrity": "sha512-wpU6L5o/0BhBsjYt4BH2J3L0+yDhxotCi6cRF7QZbm03u/tdq8tgwyOzXe+MPArh+EZhsBrnBOCdUpUhgZNRZQ==", + "dependencies": { + "@matrixai/resources": "^1.0.0", + "async-mutex": "^0.3.2", + "ts-custom-error": "^3.2.0" + } + }, + "node_modules/@matrixai/db": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.2.0.tgz", + "integrity": "sha512-JfcpZ8zbNgdQK3mpHQisCY6TKGUO5+Issh5KDvR3zBtfdSKHJLgrqweDIyLtM9D0RT5jO5HOY+lthI/8Yfi/PA==", + "dependencies": { + "@matrixai/async-init": "^1.6.0", + "@matrixai/errors": "^1.0.1", + "@matrixai/logger": "^2.1.0", + "@matrixai/resources": "^1.0.0", + "@matrixai/workers": "^1.2.5", + "@types/abstract-leveldown": "^7.2.0", + "level": "7.0.1", + "threads": "^1.6.5" + } + }, + "node_modules/@matrixai/db/node_modules/@matrixai/errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", + "integrity": "sha512-9NbIm3rPMkZz+Ma5tfKduVCWfvYzdHlO89u9mBap7FzJqXkl4yoENjMZm5Do6PvhtIYtRcm6+eTgWvHd6pkdGg==", + "dependencies": { + "ts-custom-error": "^3.2.0" + } + }, + "node_modules/@matrixai/errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", + "integrity": "sha512-9NbIm3rPMkZz+Ma5tfKduVCWfvYzdHlO89u9mBap7FzJqXkl4yoENjMZm5Do6PvhtIYtRcm6+eTgWvHd6pkdGg==", + "dependencies": { + "ts-custom-error": "^3.2.0" + } + }, + "node_modules/@matrixai/id": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@matrixai/id/-/id-3.3.2.tgz", + "integrity": "sha512-gpW56P7jZILPc0oxyNQvZBkEBn30JPGpslOHIcDoKnCZR8VGZXEKX485xy1WE4MBiQHXdGeiYF8A2CluqTnu3w==", + "dependencies": { + "multiformats": "^9.4.8", + "uuid": "^8.3.2" + } + }, + "node_modules/@matrixai/logger": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@matrixai/logger/-/logger-2.1.0.tgz", + "integrity": "sha512-UmLuXi2PJ03v0Scfl57217RPnjEZDRLlpfdIjIwCfju+kofnhhCI9P7OZu3/FgW147vbvSzWCrrtpwJiLROUUA==" + }, + "node_modules/@matrixai/resources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@matrixai/resources/-/resources-1.0.0.tgz", + "integrity": "sha512-B1ZkySZwOZTIzhK+YTN4HifOTd1dk1ifDUV8/8WgGho2nUZzIMYms7iDmW/ZHUCkqvWupKY6AYvfwnKBOJJnWg==" + }, + "node_modules/@matrixai/workers": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.2.5.tgz", + "integrity": "sha512-ikI4K6RGKQbG68it7TXJJ5wX2csW+WpokUehTnz5r66d7o6FC3PkojE46LPLCDSwk3NVCGoQ743OZS2nuA8SRA==", + "dependencies": { + "@matrixai/logger": "^2.1.0", + "threads": "^1.6.5", + "ts-custom-error": "^3.2.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@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": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "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.16", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", + "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "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.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/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.5", + "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.5.tgz", + "integrity": "sha512-6bgv24B+A2bo9AfzReeg5StdiijKzwwnRflA8RLd1V4Yv995LeTmo0z69/MPbBDFSiZWdZHQygLo/ccXhMEDgw==", + "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.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "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": "26.0.24", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz", + "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==", + "dev": true, + "dependencies": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/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.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.29.tgz", + "integrity": "sha512-9dDdonLyPJQJ/kdOlDxAah+bTI+u2ccF3k62FErhquDuggoCX6piWez7j7o6yNE+rP2IRcZVQ6Tw4N0P38+rWA==" + }, + "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/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 + }, + "node_modules/@types/pako": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.2.tgz", + "integrity": "sha512-8UJl2MjkqqS6ncpLZqRZ5LmGiFBkbYxocD4e4jmBqGvfRG1RS23gKsBQbdtV9O9GvRyjFTiRHRByjSlKCLlmZw==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "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.11", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.11.tgz", + "integrity": "sha512-0z+/apYJwKFz/RHp6mOMxz/y7xOvWPYPevuCEyAY3gXsjtaac02E26RvxA+I96rfvmVH/dEMGXNvyJfViR1FSQ==", + "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.1", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", + "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "5.4.0", + "@typescript-eslint/scope-manager": "5.4.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.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", + "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/typescript-estree": "5.4.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.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", + "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.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/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==", + "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.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", + "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.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.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.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/@typescript-eslint/visitor-keys/node_modules/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, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/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": "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-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-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-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, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/async-lock": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.0.tgz", + "integrity": "sha512-8A7SkiisnEgME2zEedtDYPxUPzdv3x//E7n5IFktPAtMYSEAV7eNJF0rMwrVyUFj6d/8rgajLantbjcNRQYXIg==" + }, + "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/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, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@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", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "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.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.16.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.2.2" + }, + "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": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + }, + "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/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/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/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, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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==", + "engines": { + "node": ">=0.6" + } + }, + "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.17.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", + "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001265", + "electron-to-chromium": "^1.3.867", + "escalade": "^3.1.1", + "node-releases": "^2.0.0", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/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/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, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.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.30001269", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", + "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/canonicalize": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.5.tgz", + "integrity": "sha512-mAjKJPIyP0xqqv6IAkvso07StOmz6cmGtNDg3pXCSzXVZOqka7StIkAhJl/zHOi4M2CgpYfD6aeRWbnrmtvBEA==" + }, + "node_modules/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, + "dependencies": { + "rsvp": "^4.8.4" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "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/chalk/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/chalk/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/chalk/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/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.5.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", + "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", + "dependencies": { + "css-select": "^4.1.3", + "css-what": "^5.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0", + "domutils": "^2.7.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": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/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": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/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, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/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/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "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/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 + }, + "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/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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.18.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.18.3.tgz", + "integrity": "sha512-4zP6/y0a2RTHN5bRGT7PTq9lVt3WzvffTNjqnTKsXhkAYNDTkdCLOIfAdOLcQ/7TDdyRj3c+NeHe1NmF1eDScw==", + "dev": true, + "dependencies": { + "browserslist": "^4.17.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.0", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", + "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", + "dependencies": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.1.0" + }, + "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.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", + "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", + "dependencies": { + "node-fetch": "2.6.1" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", + "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/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==", + "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.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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, + "engines": { + "node": ">=0.10" + } + }, + "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==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/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, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz", + "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=" + }, + "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": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "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.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "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.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "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.2.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", + "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "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.3.871", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", + "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/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.4.3", + "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.4.3.tgz", + "integrity": "sha512-OQqsGw3eNrMdFpiYRX17nMq1NKKebaA0KXyM9IRY9aPOxpaeOwcdvWnOcvvO9wCxZFNxgy/A2SOZdxnhCe3paA==", + "dependencies": { + "@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", + "errno": "^0.1.7", + "lexicographic-integer": "^1.1.0", + "node-forge": "^0.10.0", + "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" + } + }, + "node_modules/encryptedfs/node_modules/@matrixai/db": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-1.2.1.tgz", + "integrity": "sha512-1W8TORmRX3q3NugZFn0FTgI0mo/n0nWBTXHKXwwPfxtdyNfi18JCj3HVCwWdToOo87ypnS/mqLDIUTSHbF7F3Q==", + "dependencies": { + "@matrixai/async-init": "^1.6.0", + "@matrixai/logger": "^2.1.0", + "@matrixai/workers": "^1.2.5", + "abstract-leveldown": "^7.2.0", + "async-mutex": "^0.3.1", + "level": "7.0.1", + "levelup": "^5.1.1", + "sublevel-prefixer": "^1.0.0", + "subleveldown": "^6.0.1", + "threads": "^1.6.5", + "ts-custom-error": "^3.2.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/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, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/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.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-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.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "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/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, + "engines": { + "node": ">=0.10.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": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "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", + "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", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/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, + "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.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", + "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "find-up": "^2.1.0", + "pkg-dir": "^2.0.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-module-utils/node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/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==", + "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.1", + "has": "^1.0.3", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.5", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.11.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-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==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.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-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/node_modules/@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, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "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/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/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-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "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/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/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/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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/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": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "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.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "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/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 + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/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/execa/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/execa/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/execa/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/execa/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/execa/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/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/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==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/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, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/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, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/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, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.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.10.10", + "resolved": "https://registry.npmjs.org/fast-fuzzy/-/fast-fuzzy-1.10.10.tgz", + "integrity": "sha512-TkXYYQcLyZ5tbDpg3kj5gq7PNl6vQQQEW99/sBpmYYRPcuCaZElm3FpoOOqwL51+1prhjrzsnGAjWgNCG7iVOA==", + "dependencies": { + "graphemesplit": "^2.4.1" + } + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "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" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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-extra/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/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/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/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/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/gauge/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/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==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "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/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.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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==" + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "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/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 + }, + "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/handlebars/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/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.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "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-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "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/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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 + }, + "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.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.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.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "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.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "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.3.3", + "resolved": "https://registry.npmjs.org/ip-num/-/ip-num-1.3.3.tgz", + "integrity": "sha512-1QsiMKglDaemuIktincG1ntr3DvVTV/pU++eyG7vIm4xd+gvtJ9eoB34RRbI9YTqn1U5og16n7+1RgwLhv4RmA==", + "dependencies": { + "big-integer": "^1.6.48" + } + }, + "node_modules/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, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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-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, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "optional": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-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==", + "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.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "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-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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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.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==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "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.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "dependencies": { + "call-bind": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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==", + "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": "^3.0.2" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.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-lib-source-maps/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/istanbul-reports": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", + "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "dev": true, + "dependencies": { + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-changed-files/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/jest-changed-files/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-changed-files/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/jest-changed-files/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/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.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" + }, + "engines": { + "node": ">= 10.14.2" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^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", + "walker": "^1.0.7" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@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", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "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" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "dev": true, + "dependencies": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "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==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/jest-mock-props/-/jest-mock-props-1.9.0.tgz", + "integrity": "sha512-8IlIiZRvovnRuvqcvWZyDv4CyhrUGTbEW/1eKurHr2JY4VhIWQIPlbpt9lqL2nxdGnco+OcgpPBwGYCEeDb2+A==", + "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": "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==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "dev": true, + "dependencies": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@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", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "dependencies": { + "@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", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "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", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "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-runtime/node_modules/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, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/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, + "dependencies": { + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/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, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.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", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "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/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": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.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": "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/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/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/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/jest/node_modules/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, + "dependencies": { + "@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" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/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/jest/node_modules/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, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/jest/node_modules/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, + "dependencies": { + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/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, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jose": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.3.6.tgz", + "integrity": "sha512-A/JgZGUerqG2IMuxkUDBtZ4aTxg/l1Y+pt/QAAYiRAR3EFlxIE0Su0xdpB8tQcPZK5eudB7g1PHCZ5uHatbY+g==", + "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/jsdom/node_modules/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, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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/jsonfile/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/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, + "engines": { + "node": ">=0.10.0" + } + }, + "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-option-wrap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/level-option-wrap/-/level-option-wrap-1.1.0.tgz", + "integrity": "sha1-rSDmjZ88IsiJdTHMaqevWWse0Sk=", + "dependencies": { + "defined": "~0.0.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.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "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.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 + }, + "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.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/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 + }, + "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.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "dependencies": { + "tmpl": "1.0.x" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/marked": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", + "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==", + "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.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "dev": true, + "dependencies": { + "mime-db": "1.50.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": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "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/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, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/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.4.9", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.4.9.tgz", + "integrity": "sha512-zA84TTJcRfRMpjvYqy63piBbSEdqlIGqNNSpP6kspqtougqjo60PRhIFo+oAxrjkof14WMCImvr7acK6rPpXLw==" + }, + "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/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.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-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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-notifier": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.1.tgz", + "integrity": "sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.5", + "shellwords": "^0.1.1", + "uuid": "^8.3.2", + "which": "^2.0.2" + } + }, + "node_modules/node-notifier/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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 + }, + "node_modules/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, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/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/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": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/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/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-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/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, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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-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, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "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.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "dependencies": { + "node-modules-regexp": "^1.0.0" + }, + "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/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/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/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "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-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "node_modules/pkg-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=", + "dev": true + }, + "node_modules/pkg-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=", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "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/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/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, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/printj": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", + "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", + "bin": { + "printj": "bin/printj.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "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/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/reachdown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reachdown/-/reachdown-1.1.0.tgz", + "integrity": "sha512-6LsdRe4cZyOjw4NnvbhUd/rGG7WQ9HMopPr+kyL018Uci4kijtxcGR5kVb5Ln13k4PEE+fEFQbjfOvNw7cnXmA==", + "engines": { + "node": ">=6" + } + }, + "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/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, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "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": "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==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "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/regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", + "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^9.0.0", + "regjsgen": "^0.5.2", + "regjsparser": "^0.7.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", + "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "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/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 + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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/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 + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "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-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "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/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, + "engines": { + "node": ">=0.12" + } + }, + "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/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true, + "engines": { + "node": "6.* || >= 7.*" + } + }, + "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/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", + "dev": true, + "dependencies": { + "@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" + }, + "bin": { + "sane": "src/cli.js" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/sane/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/sane/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/sane/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/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, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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 + }, + "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.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "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": "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==", + "dependencies": { + "decompress-response": "^4.2.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/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, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/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, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/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, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/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/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/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-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/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 + }, + "node_modules/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, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/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 + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.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/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, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/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, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/sublevel-prefixer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sublevel-prefixer/-/sublevel-prefixer-1.0.0.tgz", + "integrity": "sha1-TuRZ72Y6yFvyj8ZJ17eWX9ppEHM=" + }, + "node_modules/subleveldown": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/subleveldown/-/subleveldown-6.0.1.tgz", + "integrity": "sha512-Cnf+cn2wISXU2xflY1SFIqfX4hG2d6lFk2P5F8RDQLmiqN9Ir4ExNfUFH6xnmizMseM/t+nMsDUKjN9Kw6ShFA==", + "dependencies": { + "abstract-leveldown": "^7.2.0", + "encoding-down": "^7.1.0", + "inherits": "^2.0.3", + "level-option-wrap": "^1.1.0", + "levelup": "^5.1.1", + "reachdown": "^1.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "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/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/table": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", + "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dev": true, + "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/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": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "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-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, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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": "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==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^26.1.0", + "json5": "2.x", + "lodash": "4.x", + "make-error": "1.x", + "mkdirp": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "jest": ">=26 <27", + "typescript": ">=3.8 <5.0" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "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", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "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, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "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.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/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.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/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, + "dependencies": { + "@types/node": "^12.12.7", + "fs-extra": "^8.1.0", + "tslib": "^1.10.0" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/typescript-cached-transpile/node_modules/@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 + }, + "node_modules/typescript-cached-transpile/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/typescript-cached-transpile/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/typescript-cached-transpile/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/uglify-js": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", + "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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/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, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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/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, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.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-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==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.10.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/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, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "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.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "dependencies": { + "makeerror": "1.0.x" + } + }, + "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/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 + }, + "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==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "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.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", + "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==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/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": { "@babel/code-frame": { "version": "7.15.8", @@ -308,9 +12906,9 @@ } }, "@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.16.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz", + "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==", "dev": true }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { @@ -1078,12 +13676,12 @@ } }, "@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.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.14.9", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" } }, @@ -1416,6 +14014,33 @@ "semver": "^6.3.0" } }, + "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.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1864,9 +14489,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.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.29.tgz", + "integrity": "sha512-9dDdonLyPJQJ/kdOlDxAah+bTI+u2ccF3k62FErhquDuggoCX6piWez7j7o6yNE+rP2IRcZVQ6Tw4N0P38+rWA==" }, "@types/node-forge": { "version": "0.9.10", @@ -2093,7 +14718,8 @@ "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", @@ -3705,7 +16331,8 @@ "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 + "dev": true, + "requires": {} }, "eslint-import-resolver-node": { "version": "0.3.6", @@ -4274,13 +16901,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": { @@ -5854,19 +18474,22 @@ "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 + "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", @@ -6554,13 +19177,6 @@ "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": { @@ -6702,9 +19318,9 @@ } }, "marked": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/marked/-/marked-3.0.7.tgz", - "integrity": "sha512-ctKqbnLuNbsHbI26cfMyOlKgXGfl1orOv1AvWWDX7AkgfMOwCWvmuYc+mVLeWhQ9W6hdWVBynOs96VkcscKo0Q==", + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", + "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==", "dev": true }, "md5.js": { @@ -6986,10 +19602,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", @@ -7004,17 +19619,18 @@ "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==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.1.tgz", + "integrity": "sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==", "dev": true, "optional": true, + "peer": true, "requires": { "growly": "^1.3.0", "is-wsl": "^2.2.0", - "semver": "^7.3.2", + "semver": "^7.3.5", "shellwords": "^0.1.1", - "uuid": "^8.3.0", + "uuid": "^8.3.2", "which": "^2.0.2" }, "dependencies": { @@ -7024,6 +19640,7 @@ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "optional": true, + "peer": true, "requires": { "lru-cache": "^6.0.0" } @@ -7036,12 +19653,6 @@ "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=", - "dev": true - }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -7242,32 +19853,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", @@ -7436,45 +20021,28 @@ } }, "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==", - "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==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -7499,12 +20067,6 @@ "requires": { "has-flag": "^4.0.0" } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true } } }, @@ -7518,17 +20080,18 @@ } }, "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": { @@ -7548,10 +20111,19 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, "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" @@ -7565,6 +20137,28 @@ "requires": { "has-flag": "^4.0.0" } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } } } }, @@ -7575,9 +20169,9 @@ "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", @@ -7586,15 +20180,13 @@ "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" } }, "prelude-ls": { @@ -8231,13 +20823,13 @@ "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" } }, @@ -8591,6 +21183,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", @@ -8630,14 +21230,6 @@ "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" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -9085,31 +21677,42 @@ } }, "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" + "marked": "^4.0.12", + "minimatch": "^5.0.1", + "shiki": "^0.10.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "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": { + "brace-expansion": "^2.0.1" + } + } } }, - "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==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", "dev": true }, "typescript-cached-transpile": { @@ -9325,13 +21928,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": { @@ -9374,6 +21970,12 @@ "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", "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", @@ -9465,12 +22067,6 @@ "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", @@ -9524,7 +22120,8 @@ "version": "7.5.5", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true + "dev": true, + "requires": {} }, "xml": { "version": "1.0.1", diff --git a/package.json b/package.json index 1f45d3202..6e592eb7b 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "test": "jest", "lint": "eslint '{src,tests}/**/*.{js,ts}'", "lintfix": "eslint '{src,tests}/**/*.{js,ts}' --fix", - "docs": "rimraf ./docs && typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src && touch ./docs/.nojekyll", + "docs": "rimraf ./docs && typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src", "bench": "rimraf ./benches/results && 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" @@ -114,7 +114,7 @@ "@types/google-protobuf": "^3.7.4", "@types/jest": "^26.0.20", "@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", @@ -133,14 +133,14 @@ "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", + "node-gyp-build": "4.4.0", + "pkg": "5.6.0", "prettier": "^2.2.1", "ts-jest": "^26.4.4", "ts-node": "^10.4.0", "tsconfig-paths": "^3.9.0", - "typedoc": "^0.21.5", - "typescript": "^4.1.3", + "typedoc": "^0.22.15", + "typescript": "^4.5.2", "typescript-cached-transpile": "0.0.6" } } 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..10f435f98 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 diff --git a/tsconfig.json b/tsconfig.json index d4abc0d16..8e4424ab2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,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} ''; From 37a6d62256f5622bad5b5b174f39767ff25b4538 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 26 Apr 2022 15:09:11 +1000 Subject: [PATCH 03/74] build: updating core libraries Updated js-async-init from 1.6.0 to 1.7.1 Updated js-async-locks from 2.0.0 to 2.2.0 Updated js-db from 3.2.0 to 3.2.3 Updating js-workers from 1.2.5 to 1.3.1 --- package-lock.json | 126 +++++++++++++++++----------------------------- package.json | 8 +-- 2 files changed, 50 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index d7ad332ff..a00bffbdb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,14 +10,14 @@ "license": "GPL-3.0", "dependencies": { "@grpc/grpc-js": "1.3.7", - "@matrixai/async-init": "^1.6.0", - "@matrixai/async-locks": "^2.0.0", - "@matrixai/db": "^3.2.0", + "@matrixai/async-init": "^1.7.1", + "@matrixai/async-locks": "^2.2.0", + "@matrixai/db": "^3.2.3", "@matrixai/errors": "^1.0.1", "@matrixai/id": "^3.3.2", "@matrixai/logger": "^2.1.0", "@matrixai/resources": "^1.0.0", - "@matrixai/workers": "^1.2.5", + "@matrixai/workers": "^1.3.1", "ajv": "^7.0.4", "bip39": "^3.0.3", "canonicalize": "^1.0.5", @@ -2287,55 +2287,39 @@ } }, "node_modules/@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==", - "dependencies": { - "async-mutex": "^0.3.2", - "ts-custom-error": "^3.2.0" - } - }, - "node_modules/@matrixai/async-init/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==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@matrixai/async-init/-/async-init-1.7.1.tgz", + "integrity": "sha512-3ELRuEn6AoC3e0b4QccA+NxZl0LilyjYeu6a3Pf9VUVB89EepnNKsk/Afb9qa+B5LvLQwmgHtg4r9VwRpQpnQA==", "dependencies": { - "tslib": "^2.3.1" + "@matrixai/async-locks": "^2.2.0", + "@matrixai/errors": "^1.0.1" } }, "node_modules/@matrixai/async-locks": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.0.0.tgz", - "integrity": "sha512-wpU6L5o/0BhBsjYt4BH2J3L0+yDhxotCi6cRF7QZbm03u/tdq8tgwyOzXe+MPArh+EZhsBrnBOCdUpUhgZNRZQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.2.0.tgz", + "integrity": "sha512-i0a551EUMhD1WKpaAyhBUt83ckbOxPB4MlOH8VDzeDyPMAtLI9egCqf3HWOvhN0rSjoH97EmzmfxyAeAgiQzTw==", "dependencies": { + "@matrixai/errors": "^1.0.1", "@matrixai/resources": "^1.0.0", - "async-mutex": "^0.3.2", - "ts-custom-error": "^3.2.0" + "async-mutex": "^0.3.2" } }, "node_modules/@matrixai/db": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.2.0.tgz", - "integrity": "sha512-JfcpZ8zbNgdQK3mpHQisCY6TKGUO5+Issh5KDvR3zBtfdSKHJLgrqweDIyLtM9D0RT5jO5HOY+lthI/8Yfi/PA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.3.1.tgz", + "integrity": "sha512-EQulm82sBhw1WRhOzzWMoij1SwpjAQHgyokxleTwFHoAnDPMi4WVy4AIxd2lJMPOhhzEFQxCqQmmMYhZWwYAPg==", "dependencies": { - "@matrixai/async-init": "^1.6.0", + "@matrixai/async-init": "^1.7.0", "@matrixai/errors": "^1.0.1", "@matrixai/logger": "^2.1.0", "@matrixai/resources": "^1.0.0", - "@matrixai/workers": "^1.2.5", + "@matrixai/workers": "^1.3.0", "@types/abstract-leveldown": "^7.2.0", "level": "7.0.1", "threads": "^1.6.5" } }, - "node_modules/@matrixai/db/node_modules/@matrixai/errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", - "integrity": "sha512-9NbIm3rPMkZz+Ma5tfKduVCWfvYzdHlO89u9mBap7FzJqXkl4yoENjMZm5Do6PvhtIYtRcm6+eTgWvHd6pkdGg==", - "dependencies": { - "ts-custom-error": "^3.2.0" - } - }, "node_modules/@matrixai/errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", @@ -2364,13 +2348,14 @@ "integrity": "sha512-B1ZkySZwOZTIzhK+YTN4HifOTd1dk1ifDUV8/8WgGho2nUZzIMYms7iDmW/ZHUCkqvWupKY6AYvfwnKBOJJnWg==" }, "node_modules/@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.1", + "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.3.1.tgz", + "integrity": "sha512-AXI37aZ7gSqS5PpUCG7/yfNcnWNYiQUp4yFBY1Z9lKk0zrkQzND1zPjDuJ2E7t6E1a4rwa8vtysj5TVeMCA8jw==", "dependencies": { + "@matrixai/async-init": "^1.7.0", + "@matrixai/errors": "^1.0.1", "@matrixai/logger": "^2.1.0", - "threads": "^1.6.5", - "ts-custom-error": "^3.2.0" + "threads": "^1.6.5" } }, "node_modules/@nodelib/fs.scandir": { @@ -14199,57 +14184,37 @@ } }, "@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.1", + "resolved": "https://registry.npmjs.org/@matrixai/async-init/-/async-init-1.7.1.tgz", + "integrity": "sha512-3ELRuEn6AoC3e0b4QccA+NxZl0LilyjYeu6a3Pf9VUVB89EepnNKsk/Afb9qa+B5LvLQwmgHtg4r9VwRpQpnQA==", "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.0", + "@matrixai/errors": "^1.0.1" } }, "@matrixai/async-locks": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.0.0.tgz", - "integrity": "sha512-wpU6L5o/0BhBsjYt4BH2J3L0+yDhxotCi6cRF7QZbm03u/tdq8tgwyOzXe+MPArh+EZhsBrnBOCdUpUhgZNRZQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.2.0.tgz", + "integrity": "sha512-i0a551EUMhD1WKpaAyhBUt83ckbOxPB4MlOH8VDzeDyPMAtLI9egCqf3HWOvhN0rSjoH97EmzmfxyAeAgiQzTw==", "requires": { + "@matrixai/errors": "^1.0.1", "@matrixai/resources": "^1.0.0", - "async-mutex": "^0.3.2", - "ts-custom-error": "^3.2.0" + "async-mutex": "^0.3.2" } }, "@matrixai/db": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.2.0.tgz", - "integrity": "sha512-JfcpZ8zbNgdQK3mpHQisCY6TKGUO5+Issh5KDvR3zBtfdSKHJLgrqweDIyLtM9D0RT5jO5HOY+lthI/8Yfi/PA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.3.1.tgz", + "integrity": "sha512-EQulm82sBhw1WRhOzzWMoij1SwpjAQHgyokxleTwFHoAnDPMi4WVy4AIxd2lJMPOhhzEFQxCqQmmMYhZWwYAPg==", "requires": { - "@matrixai/async-init": "^1.6.0", + "@matrixai/async-init": "^1.7.0", "@matrixai/errors": "^1.0.1", "@matrixai/logger": "^2.1.0", "@matrixai/resources": "^1.0.0", - "@matrixai/workers": "^1.2.5", + "@matrixai/workers": "^1.3.0", "@types/abstract-leveldown": "^7.2.0", "level": "7.0.1", "threads": "^1.6.5" - }, - "dependencies": { - "@matrixai/errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", - "integrity": "sha512-9NbIm3rPMkZz+Ma5tfKduVCWfvYzdHlO89u9mBap7FzJqXkl4yoENjMZm5Do6PvhtIYtRcm6+eTgWvHd6pkdGg==", - "requires": { - "ts-custom-error": "^3.2.0" - } - } } }, "@matrixai/errors": { @@ -14280,13 +14245,14 @@ "integrity": "sha512-B1ZkySZwOZTIzhK+YTN4HifOTd1dk1ifDUV8/8WgGho2nUZzIMYms7iDmW/ZHUCkqvWupKY6AYvfwnKBOJJnWg==" }, "@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.1", + "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.3.1.tgz", + "integrity": "sha512-AXI37aZ7gSqS5PpUCG7/yfNcnWNYiQUp4yFBY1Z9lKk0zrkQzND1zPjDuJ2E7t6E1a4rwa8vtysj5TVeMCA8jw==", "requires": { + "@matrixai/async-init": "^1.7.0", + "@matrixai/errors": "^1.0.1", "@matrixai/logger": "^2.1.0", - "threads": "^1.6.5", - "ts-custom-error": "^3.2.0" + "threads": "^1.6.5" } }, "@nodelib/fs.scandir": { diff --git a/package.json b/package.json index 6e592eb7b..bcd800011 100644 --- a/package.json +++ b/package.json @@ -73,14 +73,14 @@ }, "dependencies": { "@grpc/grpc-js": "1.3.7", - "@matrixai/async-init": "^1.6.0", - "@matrixai/async-locks": "^2.0.0", - "@matrixai/db": "^3.2.0", + "@matrixai/async-init": "^1.7.1", + "@matrixai/async-locks": "^2.2.0", + "@matrixai/db": "^3.2.3", "@matrixai/errors": "^1.0.1", "@matrixai/id": "^3.3.2", "@matrixai/logger": "^2.1.0", "@matrixai/resources": "^1.0.0", - "@matrixai/workers": "^1.2.5", + "@matrixai/workers": "^1.3.1", "ajv": "^7.0.4", "bip39": "^3.0.3", "canonicalize": "^1.0.5", From 49773051cf9e51632b2bad9015bc9fe1feb32768 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 26 Apr 2022 15:12:52 +1000 Subject: [PATCH 04/74] feat: static descriptions and exit codes for all errors The `data` POJO that was originally supplied in the constructor as the second parameter is now part of the `options` parameter and most places in the code have been updated to match this. #304 --- src/ErrorPolykey.ts | 14 +-- src/acl/ACL.ts | 39 ++++---- src/acl/errors.ts | 48 ++++++--- src/agent/errors.ts | 21 ++-- src/bin/agent/CommandStart.ts | 6 +- src/bin/errors.ts | 42 ++++---- src/bin/keys/CommandDecrypt.ts | 10 +- src/bin/keys/CommandEncrypt.ts | 10 +- src/bin/keys/CommandSign.ts | 10 +- src/bin/keys/CommandVerify.ts | 10 +- src/bin/polykey-agent.ts | 2 +- src/bin/secrets/CommandCreate.ts | 10 +- src/bin/secrets/CommandEdit.ts | 10 +- src/bin/secrets/CommandUpdate.ts | 10 +- src/bin/utils/processors.ts | 40 +++++--- src/bootstrap/errors.ts | 6 +- src/claims/errors.ts | 95 +++++++++++++----- src/client/errors.ts | 18 ++-- src/discovery/errors.ts | 19 +++- src/errors.ts | 38 ++++++-- src/gestalts/errors.ts | 29 ++++-- src/git/errors.ts | 28 ++++-- src/grpc/errors.ts | 49 +++++++--- src/grpc/utils/utils.ts | 16 +-- src/identities/errors.ts | 69 +++++++++---- src/keys/KeyManager.ts | 150 +++++++++++++++++------------ src/keys/errors.ts | 84 ++++++++++++---- src/locks/Locks.ts | 14 ++- src/network/ConnectionForward.ts | 8 +- src/network/ConnectionReverse.ts | 16 +-- src/network/errors.ts | 98 ++++++++++--------- src/network/utils.ts | 86 ++++++++++------- src/nodes/NodeConnectionManager.ts | 4 +- src/nodes/errors.ts | 54 +++++------ src/notifications/errors.ts | 66 +++++++++---- src/schema/Schema.ts | 50 ++++++---- src/schema/errors.ts | 58 ++++++++--- src/sessions/errors.ts | 48 ++++++--- src/sigchain/errors.ts | 46 ++++++--- src/status/Status.ts | 64 +++++++----- src/status/errors.ts | 31 +++--- src/utils/errors.ts | 14 +-- src/validation/errors.ts | 23 +++-- src/vaults/VaultManager.ts | 20 ++-- src/vaults/errors.ts | 91 ++++++++--------- 45 files changed, 1052 insertions(+), 622 deletions(-) diff --git a/src/ErrorPolykey.ts b/src/ErrorPolykey.ts index 414b95732..17a65d04a 100644 --- a/src/ErrorPolykey.ts +++ b/src/ErrorPolykey.ts @@ -1,22 +1,18 @@ -import type { POJO } from './types'; -import { CustomError } from 'ts-custom-error'; +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, + timestamp: this.timestamp, data: this.data, + cause: this.cause, stack: this.stack, }); } diff --git a/src/acl/ACL.ts b/src/acl/ACL.ts index 2bff1d5f9..02b2868ff 100644 --- a/src/acl/ACL.ts +++ b/src/acl/ACL.ts @@ -1,9 +1,4 @@ -import type { - DB, - DBTransaction, - KeyPath, - LevelPath -} from '@matrixai/db'; +import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { PermissionId, PermissionIdString, @@ -18,15 +13,14 @@ import type { Ref } from '../types'; import Logger from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; -import { RWLockWriter } from '@matrixai/async-locks'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; -import * as aclUtils from './utils'; -import * as aclErrors from './errors'; import { utils as dbUtils } from '@matrixai/db'; import { withF } from '@matrixai/resources'; +import * as aclUtils from './utils'; +import * as aclErrors from './errors'; interface ACL extends CreateDestroyStartStop {} @CreateDestroyStartStop( @@ -36,17 +30,15 @@ interface ACL extends CreateDestroyStartStop {} class ACL { static async createACL({ db, - locks, logger = new Logger(this.name), fresh = false, }: { db: DB; - locks: Locks; logger?: Logger; fresh?: boolean; }): Promise { logger.info(`Creating ${this.name}`); - const acl = new ACL({ db, locks, logger }); + const acl = new ACL({ db, logger }); await acl.start({ fresh }); logger.info(`Created ${this.name}`); return acl; @@ -72,7 +64,7 @@ class ACL { */ protected aclVaultsDbPath: LevelPath = [this.constructor.name, 'vaults']; - // lock across the usages of the DB + // Lock across the usages of the DB // it makes sense to use // Symbol.for("key") // symbol for is found in teh global registry, if it doesn't exist, it is added to the global registry and returned @@ -99,10 +91,9 @@ class ACL { protected generatePermId: () => PermissionId; - constructor({ db, locks, logger }: { db: DB; locks: Locks; logger: Logger }) { + constructor({ db, logger }: { db: DB; logger: Logger }) { this.logger = logger; this.db = db; - this.locks = locks; } public async start({ @@ -135,24 +126,32 @@ class ACL { nodeId2: NodeId, tran?: DBTransaction, ): Promise { - const nodeId1Path = [...this.aclNodesDbPath, nodeId1.toBuffer()] as unknown as KeyPath; - const nodeId2Path = [...this.aclNodesDbPath, nodeId2.toBuffer()] as unknown as KeyPath; + const nodeId1Path = [ + ...this.aclNodesDbPath, + nodeId1.toBuffer(), + ] as unknown as KeyPath; + const nodeId2Path = [ + ...this.aclNodesDbPath, + nodeId2.toBuffer(), + ] as unknown as KeyPath; if (tran == null) { return withF( [ this.db.transaction(), this.locks.lockRead( dbUtils.keyPathToKey(nodeId1Path).toString('binary'), - dbUtils.keyPathToKey(nodeId2Path).toString('binary') + dbUtils.keyPathToKey(nodeId2Path).toString('binary'), ), ], - async ([tran]) => this.sameNodePerm(nodeId1, nodeId2, tran) + async ([tran]) => this.sameNodePerm(nodeId1, nodeId2, tran), ); } const permId1 = await tran.get(nodeId1Path, true); const permId2 = await tran.get(nodeId2Path, true); if (permId1 != null && permId2 != null) { - return IdInternal.fromBuffer(permId1).equals(IdInternal.fromBuffer(permId2)); + return IdInternal.fromBuffer(permId1).equals( + IdInternal.fromBuffer(permId2), + ); } return 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/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/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..c45691596 100644 --- a/src/bin/keys/CommandDecrypt.ts +++ b/src/bin/keys/CommandDecrypt.ts @@ -52,10 +52,12 @@ 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, + }, }); } cryptoMessage.setData(cipherText); diff --git a/src/bin/keys/CommandEncrypt.ts b/src/bin/keys/CommandEncrypt.ts index dac9d52eb..3d8ddc601 100644 --- a/src/bin/keys/CommandEncrypt.ts +++ b/src/bin/keys/CommandEncrypt.ts @@ -52,10 +52,12 @@ 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, + }, }); } cryptoMessage.setData(plainText); diff --git a/src/bin/keys/CommandSign.ts b/src/bin/keys/CommandSign.ts index 4d94d2a24..e69007eb6 100644 --- a/src/bin/keys/CommandSign.ts +++ b/src/bin/keys/CommandSign.ts @@ -52,10 +52,12 @@ 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, + }, }); } cryptoMessage.setData(data); diff --git a/src/bin/keys/CommandVerify.ts b/src/bin/keys/CommandVerify.ts index 42dabed70..c8c094193 100644 --- a/src/bin/keys/CommandVerify.ts +++ b/src/bin/keys/CommandVerify.ts @@ -60,10 +60,12 @@ 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, + }, }); } cryptoMessage.setData(data); 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..f2e2f1c3e 100644 --- a/src/bin/secrets/CommandCreate.ts +++ b/src/bin/secrets/CommandCreate.ts @@ -65,10 +65,12 @@ 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, + }, }); } secretMessage.setSecretContent(content); diff --git a/src/bin/secrets/CommandEdit.ts b/src/bin/secrets/CommandEdit.ts index f3d005810..d1ac4e36f 100644 --- a/src/bin/secrets/CommandEdit.ts +++ b/src/bin/secrets/CommandEdit.ts @@ -74,10 +74,12 @@ 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, + }, }); } secretMessage.setVault(vaultMessage); diff --git a/src/bin/secrets/CommandUpdate.ts b/src/bin/secrets/CommandUpdate.ts index 941006aed..c7fb3a6fb 100644 --- a/src/bin/secrets/CommandUpdate.ts +++ b/src/bin/secrets/CommandUpdate.ts @@ -65,10 +65,12 @@ 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, + }, }); } secretMessage.setSecretContent(content); diff --git a/src/bin/utils/processors.ts b/src/bin/utils/processors.ts index 509134fc0..d41487173 100644 --- a/src/bin/utils/processors.ts +++ b/src/bin/utils/processors.ts @@ -89,10 +89,12 @@ 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, + }, }); } } else if (typeof process.env['PK_PASSWORD'] === 'string') { @@ -131,10 +133,12 @@ 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, + }, }); } } else if (!existing && typeof process.env['PK_PASSWORD'] === 'string') { @@ -167,10 +171,12 @@ 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, + }, }); } } else if (typeof process.env['PK_RECOVERY_CODE'] === 'string') { @@ -372,10 +378,12 @@ 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, + }, }); } meta = clientUtils.encodeAuthFromPassword(password); 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..9685201f8 100644 --- a/src/claims/errors.ts +++ b/src/claims/errors.ts @@ -1,54 +1,103 @@ -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< + T, +> extends ErrorSchemaValidate { + static description = 'Claim data does not match schema'; + exitCode = sysexits.CONFIG; +} -class ErrorDoublySignedClaimValidationFailed extends ErrorSchemaValidate {} +class ErrorDoublySignedClaimValidationFailed< + T, +> extends ErrorSchemaValidate { + static description = 'Claim data does not match schema'; + exitCode = sysexits.CONFIG; +} export { ErrorClaims, 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/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..10d662ed3 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,26 +1,44 @@ 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 ErrorPolykeyAgentRunning extends ErrorPolykey { + static description = 'PolykeyAgent is running'; + exitCode = sysexits.USAGE; +} -class ErrorPolykeyAgentNotRunning extends ErrorPolykey {} +class ErrorPolykeyAgentNotRunning extends ErrorPolykey { + static description = 'PolykeyAgent is not running'; + exitCode = sysexits.USAGE; +} -class ErrorPolykeyAgentDestroyed extends ErrorPolykey {} +class ErrorPolykeyAgentDestroyed extends ErrorPolykey { + static description = 'PolykeyAgent is destroyed'; + exitCode = sysexits.USAGE; +} -class ErrorPolykeyClientRunning extends ErrorPolykey {} +class ErrorPolykeyClientRunning extends ErrorPolykey { + static description = 'PolykeyClient is running'; + exitCode = sysexits.USAGE; +} -class ErrorPolykeyClientNotRunning extends ErrorPolykey {} +class ErrorPolykeyClientNotRunning extends ErrorPolykey { + static description = 'PolykeyClient is not running'; + exitCode = sysexits.USAGE; +} -class ErrorPolykeyClientDestroyed extends ErrorPolykey {} +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, 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/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/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..0a223c1a9 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -168,7 +168,7 @@ function fromError(error: Error): ServerStatusResponse { } metadata.set('name', error.name); metadata.set('message', error.message); - metadata.set('data', JSON.stringify((error as errors.ErrorPolykey).data)); + metadata.set('data', JSON.stringify((error as errors.ErrorPolykey).data)); return { metadata, }; @@ -178,7 +178,7 @@ 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 { +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; @@ -197,12 +197,14 @@ function toError(e: ServiceError): errors.ErrorPolykey { errorData != null && errorName in errors ) { - return new errors[errorName](errorMessage, JSON.parse(errorData)); + return new errors[errorName](errorMessage, { data: JSON.parse(errorData) }); } else { - return new grpcErrors.ErrorGRPCClientCall(e.message, { - code: e.code, - details: e.details, - metadata: e.metadata.getMap(), + return new grpcErrors.ErrorGRPCClientCall(e.message, { + data: { + code: e.code, + details: e.details, + metadata: e.metadata.getMap(), + }, }); } } diff --git a/src/identities/errors.ts b/src/identities/errors.ts index 0effd2306..dece95ffc 100644 --- a/src/identities/errors.ts +++ b/src/identities/errors.ts @@ -1,24 +1,51 @@ -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/keys/KeyManager.ts b/src/keys/KeyManager.ts index 8addec87c..22d1a4329 100644 --- a/src/keys/KeyManager.ts +++ b/src/keys/KeyManager.ts @@ -269,10 +269,12 @@ 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, + }, }); } try { @@ -414,10 +416,12 @@ 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, + }, }); } await this.garbageCollectRootCerts(); @@ -535,10 +539,12 @@ 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, + }, }); } } @@ -630,10 +636,12 @@ 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, + }, }); } return true; @@ -649,10 +657,12 @@ 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, + }, }); } let keyPair; @@ -693,10 +703,12 @@ 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, + }, }); } } @@ -717,10 +729,12 @@ 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, + }, }); } const rootKeyPairBits = keysUtils.publicKeyBitSize( @@ -764,10 +778,12 @@ 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, + }, }); } return true; @@ -780,10 +796,12 @@ 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, + }, }); } let keysDbKeyPlain; @@ -814,10 +832,12 @@ 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, + }, }); } } @@ -855,10 +875,12 @@ 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, + }, }); } return true; @@ -873,10 +895,12 @@ 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, + }, }); } const rootCert = keysUtils.certFromPem(rootCertPem); @@ -894,10 +918,12 @@ 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, + }, }); } } @@ -913,10 +939,12 @@ 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, + }, }); } rootCertsNames.sort((a, b) => { @@ -950,10 +978,12 @@ 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, + }, }); } 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/locks/Locks.ts b/src/locks/Locks.ts index a91ad1807..2434d30dd 100644 --- a/src/locks/Locks.ts +++ b/src/locks/Locks.ts @@ -1,5 +1,5 @@ import type { ResourceAcquire, ResourceRelease } from '@matrixai/resources'; -import type { NonEmptyArray } from '@/types'; +import type { NonEmptyArray } from '../types'; import { RWLockWriter } from '@matrixai/async-locks'; /** @@ -18,7 +18,9 @@ class Locks { * The ids will be sorted before locking to ensure lock-hierarchy * in order to prevent deadlocks */ - public lockRead(...ids: NonEmptyArray): ResourceAcquire> { + public lockRead( + ...ids: NonEmptyArray + ): ResourceAcquire> { return async () => { ids.sort(); const locks: Array<[string, ResourceRelease, RWLockWriter]> = []; @@ -55,7 +57,7 @@ class Locks { } } }, - locks.map(([,,lock]) => lock) as NonEmptyArray + locks.map(([, , lock]) => lock) as NonEmptyArray, ]; }; } @@ -65,7 +67,9 @@ class Locks { * The ids will be sorted before locking to ensure lock-hierarchy * in order to prevent deadlocks */ - public lockWrite(...ids: NonEmptyArray): ResourceAcquire> { + public lockWrite( + ...ids: NonEmptyArray + ): ResourceAcquire> { return async () => { ids.sort(); const locks: Array<[string, ResourceRelease, RWLockWriter]> = []; @@ -102,7 +106,7 @@ class Locks { } } }, - locks.map(([,,lock]) => lock) as NonEmptyArray + locks.map(([, , lock]) => lock) as NonEmptyArray, ]; }; } diff --git a/src/network/ConnectionForward.ts b/src/network/ConnectionForward.ts index c41238a92..b28d95f2f 100644 --- a/src/network/ConnectionForward.ts +++ b/src/network/ConnectionForward.ts @@ -165,9 +165,11 @@ 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, + }, }); } finally { clearInterval(punchInterval); diff --git a/src/network/ConnectionReverse.ts b/src/network/ConnectionReverse.ts index a746454bf..265bdaa4a 100644 --- a/src/network/ConnectionReverse.ts +++ b/src/network/ConnectionReverse.ts @@ -157,9 +157,11 @@ 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, + }, }); } finally { clearInterval(punchInterval); @@ -247,9 +249,11 @@ 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, + }, }); } tlsSocket.on('error', async (e) => { 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..08dab06ff 100644 --- a/src/network/utils.ts +++ b/src/network/utils.ts @@ -201,11 +201,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 +216,10 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainNameInvalid( 'Chain certificate common name attribute is missing', { - cert, - certIndex, + data: { + cert, + certIndex, + }, }, ); } @@ -224,10 +228,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 +241,10 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainSignatureInvalid( 'Chain certificate does not have a valid node-signature', { - cert, - certIndex, + data: { + cert, + certIndex, + }, }, ); } @@ -251,7 +259,7 @@ function verifyServerCertificateChain( throw new networkErrors.ErrorCertChainUnclaimed( 'Node ID is not claimed by any certificate', { - nodeId, + data: { nodeId }, }, ); } @@ -268,9 +276,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 +306,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 +321,10 @@ function verifyClientCertificateChain(certChain: Array): void { throw new networkErrors.ErrorCertChainNameInvalid( 'Chain certificate common name attribute is missing', { - cert, - certIndex, + data: { + cert, + certIndex, + }, }, ); } @@ -319,10 +333,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 +346,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 +361,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/NodeConnectionManager.ts b/src/nodes/NodeConnectionManager.ts index 5338e0058..b7c68dfa9 100644 --- a/src/nodes/NodeConnectionManager.ts +++ b/src/nodes/NodeConnectionManager.ts @@ -15,6 +15,8 @@ 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,8 +26,6 @@ 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 { withF } from '@matrixai/resources'; -import { RWLockWriter } from '@matrixai/async-locks'; type ConnectionAndLock = { connection?: NodeConnection; 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/errors.ts b/src/notifications/errors.ts index 5d6f68493..3a9ca102f 100644 --- a/src/notifications/errors.ts +++ b/src/notifications/errors.ts @@ -1,39 +1,71 @@ -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< + T, +> 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/schema/Schema.ts b/src/schema/Schema.ts index 33c50fa45..9c107acff 100644 --- a/src/schema/Schema.ts +++ b/src/schema/Schema.ts @@ -82,10 +82,12 @@ 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, + }, }); } } @@ -93,10 +95,12 @@ 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, + }, }); } const stateVersion = await this.readVersion(); @@ -126,10 +130,12 @@ 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, + }, }); } this.logger.info(`Destroyed ${this.constructor.name}`); @@ -148,10 +154,12 @@ 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, + }, }); } const stateVersion = parseInt(stateVersionData.trim()); @@ -172,10 +180,12 @@ 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, + }, }); } }); 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/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/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..5a248ba9f 100644 --- a/src/status/Status.ts +++ b/src/status/Status.ts @@ -112,10 +112,12 @@ 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, + }, }); } while (!lock(statusFile.fd)) { @@ -126,10 +128,12 @@ 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, + }, }); } if (statusData === '') { @@ -145,7 +149,7 @@ class Status { throw new statusErrors.ErrorStatusParse( 'StatusInfo validation failed', { - errors: statusUtils.statusValidate.errors, + data: { errors: statusUtils.statusValidate.errors }, }, ); } @@ -182,10 +186,12 @@ 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, + }, }); } } finally { @@ -207,10 +213,12 @@ 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, + }, }); } while (!lock(statusFile.fd)) { @@ -221,10 +229,12 @@ 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, + }, }); } let statusInfo; @@ -237,7 +247,7 @@ class Status { throw new statusErrors.ErrorStatusParse( 'StatusInfo validation failed', { - errors: statusUtils.statusValidate.errors, + data: { errors: statusUtils.statusValidate.errors }, }, ); } @@ -256,10 +266,12 @@ 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, + }, }); } return statusInfo; 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/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/validation/errors.ts b/src/validation/errors.ts index e918ce38b..f6267ba51 100644 --- a/src/validation/errors.ts +++ b/src/validation/errors.ts @@ -1,20 +1,20 @@ -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; + public errors: Array>; constructor(message, data) { super(message, data); if (data.errors != null) { - const errors: Array = []; + const errors: Array> = []; for (const eData of data.errors) { - const errorParse = new ErrorParse(eData.message); + const errorParse = new ErrorParse(eData.message); errorParse.keyPath = eData.keyPath; errorParse.value = eData.value; errorParse.context = eData.context; @@ -28,7 +28,7 @@ class ErrorValidation extends ErrorPolykey { * This packages an `ErrorParse` array into the `data` property * This is to allow encoding to and decoding from GRPC errors */ - static createFromErrors(errors: Array): ErrorValidation { + static createFromErrors(errors: Array>): ErrorValidation { const message = errors.map((e) => e.message).join('; '); const data = { errors: errors.map((e) => ({ @@ -38,7 +38,7 @@ class ErrorValidation extends ErrorPolykey { context: e.context, })), }; - const e = new ErrorValidation(message, data); + const e = new ErrorValidation(message, data); e.errors = errors; return e; } @@ -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/VaultManager.ts b/src/vaults/VaultManager.ts index 71699d1ae..13f57b5e4 100644 --- a/src/vaults/VaultManager.ts +++ b/src/vaults/VaultManager.ts @@ -199,10 +199,12 @@ class VaultManager { throw new vaultsErrors.ErrorVaultManagerKey(); } 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, + }, }); } this.vaultsDb = vaultsDb; @@ -934,10 +936,12 @@ 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, + }, }); } } 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; } From b14b240b7f8a9c8ad41576baece48b514e1bdd8d Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Wed, 27 Apr 2022 11:28:59 +1000 Subject: [PATCH 05/74] feat: using `cause` property to establish error chain When any error is thrown as the result of another error occurring, the original error is now contained within the `cause` property of the new error. #304 --- src/bin/keys/CommandDecrypt.ts | 1 + src/bin/keys/CommandEncrypt.ts | 1 + src/bin/keys/CommandSign.ts | 1 + src/bin/keys/CommandVerify.ts | 1 + src/bin/nodes/CommandPing.ts | 2 +- src/bin/secrets/CommandCreate.ts | 1 + src/bin/secrets/CommandEdit.ts | 1 + src/bin/secrets/CommandUpdate.ts | 1 + src/bin/utils/processors.ts | 4 ++++ src/grpc/GRPCClient.ts | 8 +++++--- src/grpc/GRPCServer.ts | 10 ++++++---- .../providers/github/GitHubProvider.ts | 8 +++++++- src/keys/KeyManager.ts | 19 +++++++++++++++++-- src/network/ConnectionForward.ts | 1 + src/network/ConnectionReverse.ts | 2 ++ src/network/utils.ts | 2 +- src/nodes/NodeConnection.ts | 2 +- src/notifications/utils.ts | 2 +- src/schema/Schema.ts | 5 +++++ src/status/Status.ts | 12 +++++++++--- src/validation/utils.ts | 2 ++ src/vaults/VaultInternal.ts | 4 ++-- src/vaults/VaultManager.ts | 4 +++- src/vaults/VaultOps.ts | 3 +++ 24 files changed, 77 insertions(+), 20 deletions(-) diff --git a/src/bin/keys/CommandDecrypt.ts b/src/bin/keys/CommandDecrypt.ts index c45691596..aeb4a5191 100644 --- a/src/bin/keys/CommandDecrypt.ts +++ b/src/bin/keys/CommandDecrypt.ts @@ -58,6 +58,7 @@ class CommandDecrypt extends CommandPolykey { 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 3d8ddc601..2edef5b08 100644 --- a/src/bin/keys/CommandEncrypt.ts +++ b/src/bin/keys/CommandEncrypt.ts @@ -58,6 +58,7 @@ class CommandEncypt extends CommandPolykey { 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 e69007eb6..4d31dee5f 100644 --- a/src/bin/keys/CommandSign.ts +++ b/src/bin/keys/CommandSign.ts @@ -58,6 +58,7 @@ class CommandSign extends CommandPolykey { 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 c8c094193..7c0a5de49 100644 --- a/src/bin/keys/CommandVerify.ts +++ b/src/bin/keys/CommandVerify.ts @@ -66,6 +66,7 @@ class CommandVerify extends CommandPolykey { code: e.code, path: e.path, }, + cause: e, }); } cryptoMessage.setData(data); diff --git a/src/bin/nodes/CommandPing.ts b/src/bin/nodes/CommandPing.ts index b22e0d19d..11913011a 100644 --- a/src/bin/nodes/CommandPing.ts +++ b/src/bin/nodes/CommandPing.ts @@ -59,7 +59,7 @@ class CommandPing extends CommandPolykey { error = new binErrors.ErrorNodePingFailed( `Failed to resolve node ID ${nodesUtils.encodeNodeId( nodeId, - )} to an address.`, + )} to an address.`, { cause: err }, ); } else { throw err; diff --git a/src/bin/secrets/CommandCreate.ts b/src/bin/secrets/CommandCreate.ts index f2e2f1c3e..26f22cbbe 100644 --- a/src/bin/secrets/CommandCreate.ts +++ b/src/bin/secrets/CommandCreate.ts @@ -71,6 +71,7 @@ class CommandCreate extends CommandPolykey { 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 d1ac4e36f..f86b37499 100644 --- a/src/bin/secrets/CommandEdit.ts +++ b/src/bin/secrets/CommandEdit.ts @@ -80,6 +80,7 @@ class CommandEdit extends CommandPolykey { 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 c7fb3a6fb..c7b9e696d 100644 --- a/src/bin/secrets/CommandUpdate.ts +++ b/src/bin/secrets/CommandUpdate.ts @@ -71,6 +71,7 @@ class CommandUpdate extends CommandPolykey { 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 d41487173..df43437d0 100644 --- a/src/bin/utils/processors.ts +++ b/src/bin/utils/processors.ts @@ -95,6 +95,7 @@ async function processPassword( code: e.code, path: e.path, }, + cause: e, }); } } else if (typeof process.env['PK_PASSWORD'] === 'string') { @@ -139,6 +140,7 @@ async function processNewPassword( code: e.code, path: e.path, }, + cause: e, }); } } else if (!existing && typeof process.env['PK_PASSWORD'] === 'string') { @@ -177,6 +179,7 @@ async function processRecoveryCode( code: e.code, path: e.path, }, + cause: e, }); } } else if (typeof process.env['PK_RECOVERY_CODE'] === 'string') { @@ -384,6 +387,7 @@ async function processAuthentication( code: e.code, path: e.path, }, + cause: e, }); } meta = clientUtils.encodeAuthFromPassword(password); diff --git a/src/grpc/GRPCClient.ts b/src/grpc/GRPCClient.ts index b55d3a275..b705e9aa5 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()) { @@ -151,8 +151,10 @@ abstract class GRPCClient { `Failed GRPC server certificate verification connecting to ${address}`, ); const e_ = new grpcErrors.ErrorGRPCClientVerification( - `${e.name}: ${e.message}`, - e.data, + `${e.name}: ${e.message}`,{ + data: e.data, + cause: e, + }, ); session.destroy(e_, http2.constants.NGHTTP2_PROTOCOL_ERROR); } diff --git a/src/grpc/GRPCServer.ts b/src/grpc/GRPCServer.ts index 7d6ab3d35..2c7edf11b 100644 --- a/src/grpc/GRPCServer.ts +++ b/src/grpc/GRPCServer.ts @@ -70,7 +70,7 @@ 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 @@ -100,8 +100,10 @@ class GRPCServer { `Failed GRPC client certificate verification connecting from ${address}`, ); const e_ = new grpcErrors.ErrorGRPCServerVerification( - `${e.name}: ${e.message}`, - e.data, + `${e.name}: ${e.message}`, { + data: e.data, + cause: e, + }, ); session.destroy(e_, http2.constants.NGHTTP2_PROTOCOL_ERROR); } else { @@ -140,7 +142,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); } diff --git a/src/identities/providers/github/GitHubProvider.ts b/src/identities/providers/github/GitHubProvider.ts index 4dc939999..122122931 100644 --- a/src/identities/providers/github/GitHubProvider.ts +++ b/src/identities/providers/github/GitHubProvider.ts @@ -120,7 +120,7 @@ class GitHubProvider extends Provider { data = await response.json(); } catch (e) { throw new identitiesErrors.ErrorProviderAuthentication( - 'Provider access token response is not valid JSON', + 'Provider access token response is not valid JSON', { cause: e }, ); } if (data.error) { @@ -200,6 +200,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 +247,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderCall( `Provider response body is not valid JSON`, + { cause: e }, ); } return { @@ -297,6 +299,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 +346,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 +418,7 @@ class GitHubProvider extends Provider { } catch (e) { throw new identitiesErrors.ErrorProviderCall( `Provider response body is not valid JSON`, + { cause: e }, ); } return { @@ -466,6 +471,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 22d1a4329..937c80d98 100644 --- a/src/keys/KeyManager.ts +++ b/src/keys/KeyManager.ts @@ -275,6 +275,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } try { @@ -422,6 +423,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } await this.garbageCollectRootCerts(); @@ -545,6 +547,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } } @@ -642,6 +645,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } return true; @@ -663,6 +667,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } let keyPair; @@ -675,7 +680,7 @@ class KeyManager { password, ); } catch (e) { - throw new keysErrors.ErrorRootKeysParse(e.message); + throw new keysErrors.ErrorRootKeysParse(e.message, { cause: e }); } return keyPair; } @@ -709,6 +714,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } } @@ -735,6 +741,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } const rootKeyPairBits = keysUtils.publicKeyBitSize( @@ -784,6 +791,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } return true; @@ -802,6 +810,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } let keysDbKeyPlain; @@ -811,7 +820,7 @@ class KeyManager { keysDbKeyCipher, ); } catch (e) { - throw new keysErrors.ErrorDBKeyParse(e.message); + throw new keysErrors.ErrorDBKeyParse(e.message, { cause: e }); } return keysDbKeyPlain; } @@ -838,6 +847,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } } @@ -881,6 +891,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } return true; @@ -901,6 +912,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } const rootCert = keysUtils.certFromPem(rootCertPem); @@ -924,6 +936,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } } @@ -945,6 +958,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } rootCertsNames.sort((a, b) => { @@ -984,6 +998,7 @@ class KeyManager { code: e.code, path: e.path, }, + cause: e, }); } return rootCertsPems; diff --git a/src/network/ConnectionForward.ts b/src/network/ConnectionForward.ts index b28d95f2f..5e8a829d4 100644 --- a/src/network/ConnectionForward.ts +++ b/src/network/ConnectionForward.ts @@ -170,6 +170,7 @@ class ConnectionForward extends Connection { errno: e.errno, syscall: e.syscall, }, + cause: e, }); } finally { clearInterval(punchInterval); diff --git a/src/network/ConnectionReverse.ts b/src/network/ConnectionReverse.ts index 265bdaa4a..ada434649 100644 --- a/src/network/ConnectionReverse.ts +++ b/src/network/ConnectionReverse.ts @@ -162,6 +162,7 @@ class ConnectionReverse extends Connection { errno: e.errno, syscall: e.syscall, }, + cause: e, }); } finally { clearInterval(punchInterval); @@ -254,6 +255,7 @@ class ConnectionReverse extends Connection { errno: e.errno, syscall: e.syscall, }, + cause: e, }); } tlsSocket.on('error', async (e) => { diff --git a/src/network/utils.ts b/src/network/utils.ts index 08dab06ff..f97f71ef9 100644 --- a/src/network/utils.ts +++ b/src/network/utils.ts @@ -101,7 +101,7 @@ 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; diff --git a/src/nodes/NodeConnection.ts b/src/nodes/NodeConnection.ts index 6788c20fe..d81ac9721 100644 --- a/src/nodes/NodeConnection.ts +++ b/src/nodes/NodeConnection.ts @@ -135,7 +135,7 @@ 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/notifications/utils.ts b/src/notifications/utils.ts index 08532f524..0f55a6620 100644 --- a/src/notifications/utils.ts +++ b/src/notifications/utils.ts @@ -78,7 +78,7 @@ 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 9c107acff..b7c66be4c 100644 --- a/src/schema/Schema.ts +++ b/src/schema/Schema.ts @@ -88,6 +88,7 @@ class Schema { code: e.code, path: e.path, }, + cause: e, }); } } @@ -101,6 +102,7 @@ class Schema { code: e.code, path: e.path, }, + cause: e, }); } const stateVersion = await this.readVersion(); @@ -136,6 +138,7 @@ class Schema { code: e.code, path: e.path, }, + cause: e, }); } this.logger.info(`Destroyed ${this.constructor.name}`); @@ -160,6 +163,7 @@ class Schema { code: e.code, path: e.path, }, + cause: e, }); } const stateVersion = parseInt(stateVersionData.trim()); @@ -186,6 +190,7 @@ class Schema { code: e.code, path: e.path, }, + cause: e, }); } }); diff --git a/src/status/Status.ts b/src/status/Status.ts index 5a248ba9f..fbee3edce 100644 --- a/src/status/Status.ts +++ b/src/status/Status.ts @@ -118,6 +118,7 @@ class Status { code: e.code, path: e.path, }, + cause: e, }); } while (!lock(statusFile.fd)) { @@ -134,6 +135,7 @@ class Status { code: e.code, path: e.path, }, + cause: e, }); } if (statusData === '') { @@ -143,7 +145,7 @@ 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( @@ -192,6 +194,7 @@ class Status { code: e.code, path: e.path, }, + cause: e, }); } } finally { @@ -219,6 +222,7 @@ class Status { code: e.code, path: e.path, }, + cause: e, }); } while (!lock(statusFile.fd)) { @@ -235,13 +239,14 @@ class Status { 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( @@ -272,6 +277,7 @@ class Status { code: e.code, path: e.path, }, + cause: e, }); } return statusInfo; @@ -311,7 +317,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/validation/utils.ts b/src/validation/utils.ts index 3ce13f258..4221e1508 100644 --- a/src/validation/utils.ts +++ b/src/validation/utils.ts @@ -227,6 +227,7 @@ function parseSeedNodes(data: any): [SeedNodes, boolean] { if (e instanceof TypeError) { throw new validationErrors.ErrorParse( 'Seed nodes must be of format `nodeId@host:port;...`', + { cause: e }, ); } throw e; @@ -245,6 +246,7 @@ function parseSeedNodes(data: any): [SeedNodes, boolean] { if (e instanceof validationErrors.ErrorParse) { throw new validationErrors.ErrorParse( 'Seed nodes must be of format `nodeId@host:port;...`', + { cause: e }, ); } throw e; diff --git a/src/vaults/VaultInternal.ts b/src/vaults/VaultInternal.ts index 76f87e13b..c7f60829b 100644 --- a/src/vaults/VaultInternal.ts +++ b/src/vaults/VaultInternal.ts @@ -376,7 +376,7 @@ 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; } @@ -551,7 +551,7 @@ 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; } diff --git a/src/vaults/VaultManager.ts b/src/vaults/VaultManager.ts index 13f57b5e4..571b8879d 100644 --- a/src/vaults/VaultManager.ts +++ b/src/vaults/VaultManager.ts @@ -196,7 +196,7 @@ class VaultManager { }); } catch (e) { if (e instanceof encryptedFsErrors.ErrorEncryptedFSKey) { - throw new vaultsErrors.ErrorVaultManagerKey(); + throw new vaultsErrors.ErrorVaultManagerKey(e.message, { cause: e }); } throw new vaultsErrors.ErrorVaultManagerEFS(e.message, { data: { @@ -205,6 +205,7 @@ class VaultManager { code: e.code, path: e.path, }, + cause: e, }); } this.vaultsDb = vaultsDb; @@ -942,6 +943,7 @@ class VaultManager { 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 }, ); } } From 18d04a71265ba52c9a4b25bc709b31fca8ec29ee Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 2 May 2022 10:13:01 +1000 Subject: [PATCH 06/74] fix: validation errors are forced to use `void` as `cause` #304 --- src/validation/errors.ts | 14 +++++++------- src/validation/utils.ts | 2 -- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/validation/errors.ts b/src/validation/errors.ts index f6267ba51..da01aff34 100644 --- a/src/validation/errors.ts +++ b/src/validation/errors.ts @@ -5,16 +5,16 @@ import { ErrorPolykey, sysexits } from '../errors'; * Generic error containing all parsing errors that occurred during * execution. */ -class ErrorValidation extends ErrorPolykey { +class ErrorValidation extends ErrorPolykey { static description = 'Input data failed validation'; exitCode = sysexits.DATAERR; - public errors: Array>; + public errors: Array; constructor(message, data) { super(message, data); if (data.errors != null) { - const errors: Array> = []; + const errors: Array = []; for (const eData of data.errors) { - const errorParse = new ErrorParse(eData.message); + const errorParse = new ErrorParse(eData.message); errorParse.keyPath = eData.keyPath; errorParse.value = eData.value; errorParse.context = eData.context; @@ -28,7 +28,7 @@ class ErrorValidation extends ErrorPolykey { * This packages an `ErrorParse` array into the `data` property * This is to allow encoding to and decoding from GRPC errors */ - static createFromErrors(errors: Array>): ErrorValidation { + static createFromErrors(errors: Array): ErrorValidation { const message = errors.map((e) => e.message).join('; '); const data = { errors: errors.map((e) => ({ @@ -38,7 +38,7 @@ class ErrorValidation extends ErrorPolykey { context: e.context, })), }; - const e = new ErrorValidation(message, data); + const e = new ErrorValidation(message, data); e.errors = errors; return e; } @@ -51,7 +51,7 @@ class ErrorValidation extends ErrorPolykey { * While JS allows us to throw POJOs directly, having a nominal type * is easier to check against */ -class ErrorParse extends AbstractError { +class ErrorParse extends AbstractError { static description: string = 'Failed to parse data into valid format'; exitCode = sysexits.DATAERR; public keyPath: Array; diff --git a/src/validation/utils.ts b/src/validation/utils.ts index 4221e1508..3ce13f258 100644 --- a/src/validation/utils.ts +++ b/src/validation/utils.ts @@ -227,7 +227,6 @@ function parseSeedNodes(data: any): [SeedNodes, boolean] { if (e instanceof TypeError) { throw new validationErrors.ErrorParse( 'Seed nodes must be of format `nodeId@host:port;...`', - { cause: e }, ); } throw e; @@ -246,7 +245,6 @@ function parseSeedNodes(data: any): [SeedNodes, boolean] { if (e instanceof validationErrors.ErrorParse) { throw new validationErrors.ErrorParse( 'Seed nodes must be of format `nodeId@host:port;...`', - { cause: e }, ); } throw e; From 99db4fa70898a4495cf1d57716534e153c6fc0d3 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 2 May 2022 17:13:36 +1000 Subject: [PATCH 07/74] feat: error serialisation/deserialisation over gRPC incorporating error chaining Our gRPC `toError` and `fromError` utils are now able to serialise and deserialise Polykey and non-Polykey errors (as well as non-errors), including the entire error chain if this exists. Also includes the ability to filter out sensitive data, for example when the error is being sent to another agent. Errors sent over the network in this way are now additionally wrapped on the receiving side in an `ErrorPolykeyRemote` to make the source of the error more clear. #304 --- src/ErrorPolykey.ts | 63 +++++-- src/agent/service/nodesChainDataGet.ts | 2 +- .../service/nodesClosestLocalNodesGet.ts | 2 +- src/agent/service/nodesCrossSignClaim.ts | 2 +- .../service/nodesHolePunchMessageSend.ts | 2 +- src/agent/service/notificationsSend.ts | 2 +- src/agent/service/vaultsGitInfoGet.ts | 2 +- src/agent/service/vaultsGitPackGet.ts | 2 +- src/agent/service/vaultsScan.ts | 2 +- src/client/service/gestaltsGestaltList.ts | 2 +- src/client/service/identitiesAuthenticate.ts | 2 +- .../service/identitiesAuthenticatedGet.ts | 2 +- .../service/identitiesInfoConnectedGet.ts | 2 +- src/client/service/identitiesInfoGet.ts | 2 +- src/client/service/keysCertsChainGet.ts | 2 +- src/client/service/vaultsList.ts | 2 +- src/client/service/vaultsLog.ts | 2 +- src/client/service/vaultsPermissionGet.ts | 2 +- src/client/service/vaultsScan.ts | 2 +- src/client/service/vaultsSecretsList.ts | 2 +- src/errors.ts | 12 ++ src/grpc/utils/utils.ts | 162 +++++++++++++++--- tests/grpc/utils.test.ts | 126 +++++++++++++- tests/grpc/utils/testService.ts | 14 +- 24 files changed, 353 insertions(+), 62 deletions(-) diff --git a/src/ErrorPolykey.ts b/src/ErrorPolykey.ts index 17a65d04a..3e418e757 100644 --- a/src/ErrorPolykey.ts +++ b/src/ErrorPolykey.ts @@ -1,20 +1,61 @@ +import type { POJO } from './types'; import { AbstractError } from '@matrixai/errors'; import sysexits from './utils/sysexits'; class ErrorPolykey extends AbstractError { static description: string = 'Polykey error'; exitCode: number = sysexits.GENERAL; - toJSON(): string { - return JSON.stringify({ - name: this.name, - description: this.description, - message: this.message, - exitCode: this.exitCode, - timestamp: this.timestamp, - data: this.data, - cause: this.cause, - stack: this.stack, - }); + public toJSON( + _key: string = '', + options: { + description?: boolean; + message?: boolean, + exitCode?: boolean, + timestamp?: boolean; + data?: boolean; + cause?: boolean; + stack?: boolean; + } = {} + ): { + type: string; + data: { + description?: string; + message?: string; + exitCode?: number, + timestamp?: Date, + data?: POJO; + cause?: T, + stack?: string + } + } { + options.description ??= true; + options.message ??= true; + options.exitCode ??= true; + options.timestamp ??= true; + options.data ??= true; + options.cause ??= true; + options.stack ??= true; + const data: POJO = {}; + if (options.description) data.description = this.description; + if (options.message) data.message = this.message; + if (options.exitCode) data.exitCode = this.exitCode; + if (options.timestamp) data.timestamp = this.timestamp; + if (options.data) data.data = this.data; + if (options.cause) { + // Propagate the options down the exception chain + // but only if the cause is another AbstractError + if (this.cause instanceof ErrorPolykey) { + data.cause = this.cause.toJSON('cause', options); + } else { + // Use `replacer` to further encode this object + data.cause = this.cause; + } + } + if (options.stack) data.stack = this.stack; + return { + type: this.name, + data + }; } } diff --git a/src/agent/service/nodesChainDataGet.ts b/src/agent/service/nodesChainDataGet.ts index 3ed37b99f..2a03bdd7a 100644 --- a/src/agent/service/nodesChainDataGet.ts +++ b/src/agent/service/nodesChainDataGet.ts @@ -37,7 +37,7 @@ function nodesChainDataGet({ sigchain }: { sigchain: Sigchain }) { callback(null, response); return; } catch (e) { - callback(grpcUtils.fromError(e)); + callback(grpcUtils.fromError(e, true)); return; } }; diff --git a/src/agent/service/nodesClosestLocalNodesGet.ts b/src/agent/service/nodesClosestLocalNodesGet.ts index 559337c9d..7e5739495 100644 --- a/src/agent/service/nodesClosestLocalNodesGet.ts +++ b/src/agent/service/nodesClosestLocalNodesGet.ts @@ -53,7 +53,7 @@ function nodesClosestLocalNodesGet({ callback(null, response); return; } catch (e) { - callback(grpcUtils.fromError(e)); + callback(grpcUtils.fromError(e, true)); return; } }; diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index 907494512..2606606ee 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -25,7 +25,7 @@ function nodesCrossSignClaim({ ) => { // 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 genClaims = grpcUtils.generatorDuplex(call, true); try { await sigchain.transaction(async (sigchain) => { const readStatus = await genClaims.read(); diff --git a/src/agent/service/nodesHolePunchMessageSend.ts b/src/agent/service/nodesHolePunchMessageSend.ts index d524e9f24..2196cceec 100644 --- a/src/agent/service/nodesHolePunchMessageSend.ts +++ b/src/agent/service/nodesHolePunchMessageSend.ts @@ -62,7 +62,7 @@ function nodesHolePunchMessageSend({ callback(null, response); return; } catch (e) { - callback(grpcUtils.fromError(e)); + callback(grpcUtils.fromError(e, true)); return; } }; diff --git a/src/agent/service/notificationsSend.ts b/src/agent/service/notificationsSend.ts index cf2b589ea..d942da04e 100644 --- a/src/agent/service/notificationsSend.ts +++ b/src/agent/service/notificationsSend.ts @@ -25,7 +25,7 @@ function notificationsSend({ callback(null, response); return; } catch (e) { - callback(grpcUtils.fromError(e)); + callback(grpcUtils.fromError(e, true)); return; } }; diff --git a/src/agent/service/vaultsGitInfoGet.ts b/src/agent/service/vaultsGitInfoGet.ts index 72f01a74c..1a043f92b 100644 --- a/src/agent/service/vaultsGitInfoGet.ts +++ b/src/agent/service/vaultsGitInfoGet.ts @@ -23,7 +23,7 @@ function vaultsGitInfoGet({ return async ( call: grpc.ServerWritableStream, ): Promise => { - const genWritable = grpcUtils.generatorWritable(call); + const genWritable = grpcUtils.generatorWritable(call, true); const request = call.request; const vaultMessage = request.getVault(); if (vaultMessage == null) { diff --git a/src/agent/service/vaultsGitPackGet.ts b/src/agent/service/vaultsGitPackGet.ts index 5528ade31..8c0d9232f 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -24,7 +24,7 @@ function vaultsGitPackGet({ return async ( call: grpc.ServerDuplexStream, ) => { - const genDuplex = grpcUtils.generatorDuplex(call); + const genDuplex = grpcUtils.generatorDuplex(call, true); const clientBodyBuffers: Uint8Array[] = []; const clientRequest = (await genDuplex.read()).value; clientBodyBuffers.push(clientRequest!.getChunk_asU8()); diff --git a/src/agent/service/vaultsScan.ts b/src/agent/service/vaultsScan.ts index 6dfd028e4..acdcfb0b1 100644 --- a/src/agent/service/vaultsScan.ts +++ b/src/agent/service/vaultsScan.ts @@ -17,7 +17,7 @@ function vaultsScan({ 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); diff --git a/src/client/service/gestaltsGestaltList.ts b/src/client/service/gestaltsGestaltList.ts index 458b5cf32..6f3c1c9ea 100644 --- a/src/client/service/gestaltsGestaltList.ts +++ b/src/client/service/gestaltsGestaltList.ts @@ -16,7 +16,7 @@ function gestaltsGestaltList({ 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); diff --git a/src/client/service/identitiesAuthenticate.ts b/src/client/service/identitiesAuthenticate.ts index 24ccf2f7e..c80378790 100644 --- a/src/client/service/identitiesAuthenticate.ts +++ b/src/client/service/identitiesAuthenticate.ts @@ -21,7 +21,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); diff --git a/src/client/service/identitiesAuthenticatedGet.ts b/src/client/service/identitiesAuthenticatedGet.ts index 1fd4bb9da..fa2ca756f 100644 --- a/src/client/service/identitiesAuthenticatedGet.ts +++ b/src/client/service/identitiesAuthenticatedGet.ts @@ -21,7 +21,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); diff --git a/src/client/service/identitiesInfoConnectedGet.ts b/src/client/service/identitiesInfoConnectedGet.ts index 399600900..865616d06 100644 --- a/src/client/service/identitiesInfoConnectedGet.ts +++ b/src/client/service/identitiesInfoConnectedGet.ts @@ -26,7 +26,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); diff --git a/src/client/service/identitiesInfoGet.ts b/src/client/service/identitiesInfoGet.ts index bbf159f55..400367140 100644 --- a/src/client/service/identitiesInfoGet.ts +++ b/src/client/service/identitiesInfoGet.ts @@ -27,7 +27,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); diff --git a/src/client/service/keysCertsChainGet.ts b/src/client/service/keysCertsChainGet.ts index 8355474fd..792b86916 100644 --- a/src/client/service/keysCertsChainGet.ts +++ b/src/client/service/keysCertsChainGet.ts @@ -15,7 +15,7 @@ function keysCertsChainGet({ 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); diff --git a/src/client/service/vaultsList.ts b/src/client/service/vaultsList.ts index d81902976..c35f51eea 100644 --- a/src/client/service/vaultsList.ts +++ b/src/client/service/vaultsList.ts @@ -19,7 +19,7 @@ function vaultsList({ // 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); diff --git a/src/client/service/vaultsLog.ts b/src/client/service/vaultsLog.ts index 99056911a..02b35a6f8 100644 --- a/src/client/service/vaultsLog.ts +++ b/src/client/service/vaultsLog.ts @@ -17,7 +17,7 @@ function vaultsLog({ 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); diff --git a/src/client/service/vaultsPermissionGet.ts b/src/client/service/vaultsPermissionGet.ts index 23780000e..bb2b24dc1 100644 --- a/src/client/service/vaultsPermissionGet.ts +++ b/src/client/service/vaultsPermissionGet.ts @@ -24,7 +24,7 @@ function vaultsPermissionGet({ 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); diff --git a/src/client/service/vaultsScan.ts b/src/client/service/vaultsScan.ts index 3d8d73a7e..0ed5ebbbe 100644 --- a/src/client/service/vaultsScan.ts +++ b/src/client/service/vaultsScan.ts @@ -19,7 +19,7 @@ function vaultsScan({ 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); diff --git a/src/client/service/vaultsSecretsList.ts b/src/client/service/vaultsSecretsList.ts index db2a1cc36..db71fc128 100644 --- a/src/client/service/vaultsSecretsList.ts +++ b/src/client/service/vaultsSecretsList.ts @@ -18,7 +18,7 @@ function vaultsSecretsList({ 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); diff --git a/src/errors.ts b/src/errors.ts index 10d662ed3..53ec7b8ed 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -6,6 +6,16 @@ class ErrorPolykeyUnimplemented extends ErrorPolykey { exitCode = sysexits.UNAVAILABLE; } +class ErrorPolykeyUnknown extends ErrorPolykey { + static description = 'Unable to deserialise to known error'; + exitCode = sysexits.UNKNOWN; +} + +class ErrorPolykeyRemote extends ErrorPolykey { + static description = 'Remote error from RPC call'; + exitCode = sysexits.UNAVAILABLE; +} + class ErrorPolykeyAgentRunning extends ErrorPolykey { static description = 'PolykeyAgent is running'; exitCode = sysexits.USAGE; @@ -44,6 +54,8 @@ export { sysexits, ErrorPolykey, ErrorPolykeyUnimplemented, + ErrorPolykeyUnknown, + ErrorPolykeyRemote, ErrorPolykeyAgentRunning, ErrorPolykeyAgentNotRunning, ErrorPolykeyAgentDestroyed, diff --git a/src/grpc/utils/utils.ts b/src/grpc/utils/utils.ts index 0a223c1a9..b75a6d21e 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -29,6 +29,7 @@ import type { } from '../types'; import type { CertificatePemChain, PrivateKeyPem } from '../../keys/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'; @@ -158,17 +159,16 @@ 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 +178,8 @@ 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] as string; // Grpc.status is an enum // this will iterate the enum values then enum keys // they will all be of string type @@ -192,14 +190,12 @@ function toError(e: ServiceError): errors.ErrorPolykey { if (isNaN(parseInt(key)) && e.code === grpc.status[key]) { if ( key === 'UNKNOWN' && - errorName != null && - errorMessage != null && - errorData != null && - errorName in errors + errorData != null ) { - return new errors[errorName](errorMessage, { data: JSON.parse(errorData) }); + const error: Error = JSON.parse(errorData, reviver); + return new errors.ErrorPolykeyRemote(error.message, { cause: error }); } else { - return new grpcErrors.ErrorGRPCClientCall(e.message, { + return new grpcErrors.ErrorGRPCClientCall(e.message, { data: { code: e.code, details: e.details, @@ -212,6 +208,124 @@ 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 AbstractError) { + // Include the standard properties from an AbstractError + return { + type: value.name, + data: { + description: value.description, + message: value.message, + timestamp: value.timestamp, + data: value.data, + cause: value.cause, + 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 otherErrors = { + 'Error': Error, + 'EvalError': EvalError, + 'RangeError': RangeError, + 'ReferenceError': ReferenceError, + 'SyntaxError': SyntaxError, + 'TypeError': TypeError, + 'URIError': URIError +}; + +/** + * 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') { + const message = value.data.message ?? ''; + if (value.type in errors) { + const error = new errors[value.type]( + message, + { + timestamp: value.data.timestamp, + data: value.data.data, + cause: value.data.cause, + }, + ); + error.exitCode = value.data.exitCode; + if (value.data.stack) { + error.stack = value.data.stack; + } + return error; + } else if (value.type in otherErrors) { + const error = new otherErrors[value.type](message); + if (value.data.stack) { + error.stack = value.data.stack; + } + return error; + } else { + const error = new errors.ErrorPolykeyUnknown('', { data: value }); + if (value.data.stack) { + error.stack = value.data.stack; + } + return error; + } + } else if (key === '') { + // The value is not an error + const error = new errors.ErrorPolykeyUnknown('', { data: 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 @@ -326,12 +440,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* () { @@ -340,7 +457,7 @@ function generatorWritable( try { vW = yield; } catch (e) { - stream.emit('error', fromError(e)); + stream.emit('error', fromError(e, sensitive)); stream.end(); return; } @@ -393,6 +510,7 @@ function promisifyWritableStreamCall( }); const g = generatorWritable( stream, + false, ) as AsyncGeneratorWritableStreamClient< TWrite, ClientWritableStream @@ -412,15 +530,18 @@ function promisifyWritableStreamCall( */ function generatorDuplex( stream: ClientDuplexStream, + sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ServerDuplexStream, + sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ClientDuplexStream | ServerDuplexStream, + sensitive: boolean = false, ) { const gR = generatorReadable(stream as any); - const gW = generatorWritable(stream as any); + const gW = generatorWritable(stream as any, sensitive); const gf = async function* () { let vR: any, vW: any; while (true) { @@ -485,6 +606,7 @@ function promisifyDuplexStreamCall( }); const g = generatorDuplex( stream, + false, ) as AsyncGeneratorDuplexStreamClient< TRead, TWrite, diff --git a/tests/grpc/utils.test.ts b/tests/grpc/utils.test.ts index c17f0457d..b2390e2fa 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,7 @@ 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 +276,7 @@ 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 +289,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/testService.ts b/tests/grpc/utils/testService.ts index 5c3356d7f..1297c354c 100644 --- a/tests/grpc/utils/testService.ts +++ b/tests/grpc/utils/testService.ts @@ -43,7 +43,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 +67,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 +131,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 +143,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 +169,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 +182,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++) { From bc356a932d9ed7963d777169e2e6ccabfff627b6 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Wed, 4 May 2022 15:14:36 +1000 Subject: [PATCH 08/74] feat: added logger to service handlers All of the agent and client service handlers are now passed a shared logger that is used to log errors to stderr. #304 --- src/ErrorPolykey.ts | 18 +-- src/agent/service/index.ts | 55 ++++---- src/agent/service/nodesChainDataGet.ts | 10 +- .../service/nodesClosestLocalNodesGet.ts | 4 + src/agent/service/nodesCrossSignClaim.ts | 12 +- .../service/nodesHolePunchMessageSend.ts | 4 + src/agent/service/notificationsSend.ts | 4 + src/agent/service/vaultsGitInfoGet.ts | 116 ++++++++-------- src/agent/service/vaultsGitPackGet.ts | 128 +++++++++--------- src/agent/service/vaultsScan.ts | 4 + src/bin/nodes/CommandPing.ts | 3 +- src/claims/errors.ts | 8 +- src/client/service/agentLockAll.ts | 8 +- src/client/service/agentStatus.ts | 4 + src/client/service/agentStop.ts | 4 + src/client/service/agentUnlock.ts | 10 +- .../service/gestaltsActionsGetByIdentity.ts | 4 + .../service/gestaltsActionsGetByNode.ts | 4 + .../service/gestaltsActionsSetByIdentity.ts | 4 + .../service/gestaltsActionsSetByNode.ts | 4 + .../service/gestaltsActionsUnsetByIdentity.ts | 4 + .../service/gestaltsActionsUnsetByNode.ts | 4 + .../service/gestaltsDiscoveryByIdentity.ts | 4 + src/client/service/gestaltsDiscoveryByNode.ts | 4 + .../service/gestaltsGestaltGetByIdentity.ts | 4 + .../service/gestaltsGestaltGetByNode.ts | 4 + src/client/service/gestaltsGestaltList.ts | 4 + .../service/gestaltsGestaltTrustByIdentity.ts | 4 + .../service/gestaltsGestaltTrustByNode.ts | 4 + src/client/service/identitiesAuthenticate.ts | 8 +- .../service/identitiesAuthenticatedGet.ts | 8 +- src/client/service/identitiesClaim.ts | 8 +- .../service/identitiesInfoConnectedGet.ts | 8 +- src/client/service/identitiesInfoGet.ts | 8 +- src/client/service/identitiesProvidersList.ts | 8 +- src/client/service/identitiesTokenDelete.ts | 8 +- src/client/service/identitiesTokenGet.ts | 8 +- src/client/service/identitiesTokenPut.ts | 8 +- src/client/service/keysCertsChainGet.ts | 8 +- src/client/service/keysCertsGet.ts | 8 +- src/client/service/keysDecrypt.ts | 8 +- src/client/service/keysEncrypt.ts | 8 +- src/client/service/keysKeyPairRenew.ts | 8 +- src/client/service/keysKeyPairReset.ts | 8 +- src/client/service/keysKeyPairRoot.ts | 8 +- src/client/service/keysPasswordChange.ts | 8 +- src/client/service/keysSign.ts | 8 +- src/client/service/keysVerify.ts | 8 +- src/client/service/nodesAdd.ts | 8 +- src/client/service/nodesClaim.ts | 8 +- src/client/service/nodesFind.ts | 8 +- src/client/service/nodesPing.ts | 8 +- src/client/service/notificationsClear.ts | 8 +- src/client/service/notificationsRead.ts | 8 +- src/client/service/notificationsSend.ts | 8 +- src/client/service/vaultsClone.ts | 4 + src/client/service/vaultsCreate.ts | 8 +- src/client/service/vaultsDelete.ts | 8 +- src/client/service/vaultsList.ts | 8 +- src/client/service/vaultsLog.ts | 8 +- src/client/service/vaultsPermissionGet.ts | 8 +- src/client/service/vaultsPermissionSet.ts | 8 +- src/client/service/vaultsPermissionUnset.ts | 8 +- src/client/service/vaultsPull.ts | 4 + src/client/service/vaultsRename.ts | 8 +- src/client/service/vaultsScan.ts | 8 +- src/client/service/vaultsSecretsDelete.ts | 8 +- src/client/service/vaultsSecretsEdit.ts | 8 +- src/client/service/vaultsSecretsGet.ts | 8 +- src/client/service/vaultsSecretsList.ts | 8 +- src/client/service/vaultsSecretsMkdir.ts | 8 +- src/client/service/vaultsSecretsNew.ts | 8 +- src/client/service/vaultsSecretsNewDir.ts | 8 +- src/client/service/vaultsSecretsRename.ts | 8 +- src/client/service/vaultsSecretsStat.ts | 4 + src/client/service/vaultsVersion.ts | 8 +- src/gestalts/utils.ts | 2 +- src/grpc/GRPCClient.ts | 3 +- src/grpc/GRPCServer.ts | 3 +- src/grpc/utils/utils.ts | 53 ++++---- src/identities/errors.ts | 3 +- .../providers/github/GitHubProvider.ts | 3 +- src/network/utils.ts | 4 +- src/nodes/NodeConnection.ts | 4 +- src/notifications/errors.ts | 4 +- src/notifications/utils.ts | 4 +- src/status/Status.ts | 8 +- src/vaults/VaultInternal.ts | 8 +- .../agent/service/nodesCrossSignClaim.test.ts | 11 +- tests/agent/service/notificationsSend.test.ts | 1 + tests/client/GRPCClientClient.test.ts | 2 +- tests/client/service/agentLockAll.test.ts | 1 + tests/client/service/agentStatus.test.ts | 1 + tests/client/service/agentStop.test.ts | 1 + tests/client/service/agentUnlock.test.ts | 1 + ...staltsActionsSetUnsetGetByIdentity.test.ts | 3 + .../gestaltsActionsSetUnsetGetByNode.test.ts | 3 + .../gestaltsDiscoveryByIdentity.test.ts | 1 + .../service/gestaltsDiscoveryByNode.test.ts | 1 + .../gestaltsGestaltGetByIdentity.test.ts | 1 + .../service/gestaltsGestaltGetByNode.test.ts | 1 + .../service/gestaltsGestaltList.test.ts | 1 + .../gestaltsGestaltTrustByIdentity.test.ts | 1 + .../gestaltsGestaltTrustByNode.test.ts | 1 + .../service/identitiesAuthenticate.test.ts | 1 + .../identitiesAuthenticatedGet.test.ts | 1 + tests/client/service/identitiesClaim.test.ts | 1 + .../identitiesInfoConnectedGet.test.ts | 1 + .../client/service/identitiesInfoGet.test.ts | 1 + .../service/identitiesProvidersList.test.ts | 1 + .../identitiesTokenPutDeleteGet.test.ts | 3 + .../client/service/keysCertsChainGet.test.ts | 1 + tests/client/service/keysCertsGet.test.ts | 1 + .../client/service/keysEncryptDecrypt.test.ts | 2 + tests/client/service/keysKeyPairRenew.test.ts | 1 + tests/client/service/keysKeyPairReset.test.ts | 1 + tests/client/service/keysKeyPairRoot.test.ts | 1 + .../client/service/keysPasswordChange.test.ts | 1 + tests/client/service/keysSignVerify.test.ts | 2 + tests/client/service/nodesAdd.test.ts | 1 + tests/client/service/nodesClaim.test.ts | 1 + tests/client/service/nodesFind.test.ts | 3 +- tests/client/service/nodesPing.test.ts | 1 + .../client/service/notificationsClear.test.ts | 1 + .../client/service/notificationsRead.test.ts | 1 + .../client/service/notificationsSend.test.ts | 1 + tests/grpc/utils.test.ts | 16 ++- 127 files changed, 666 insertions(+), 316 deletions(-) diff --git a/src/ErrorPolykey.ts b/src/ErrorPolykey.ts index 3e418e757..deba43ef2 100644 --- a/src/ErrorPolykey.ts +++ b/src/ErrorPolykey.ts @@ -9,24 +9,24 @@ class ErrorPolykey extends AbstractError { _key: string = '', options: { description?: boolean; - message?: boolean, - exitCode?: boolean, + message?: boolean; + exitCode?: boolean; timestamp?: boolean; data?: boolean; cause?: boolean; stack?: boolean; - } = {} + } = {}, ): { type: string; data: { description?: string; message?: string; - exitCode?: number, - timestamp?: Date, + exitCode?: number; + timestamp?: Date; data?: POJO; - cause?: T, - stack?: string - } + cause?: T; + stack?: string; + }; } { options.description ??= true; options.message ??= true; @@ -54,7 +54,7 @@ class ErrorPolykey extends AbstractError { if (options.stack) data.stack = this.stack; return { type: this.name, - data + data, }; } } diff --git a/src/agent/service/index.ts b/src/agent/service/index.ts index aa96bfd2e..caa8c60ed 100644 --- a/src/agent/service/index.ts +++ b/src/agent/service/index.ts @@ -1,16 +1,15 @@ -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 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 +23,11 @@ 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, + logger = new Logger(createService.name), + ...containerRest +}: { keyManager: KeyManager; vaultManager: VaultManager; nodeConnectionManager: NodeConnectionManager; @@ -35,23 +38,25 @@ 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, + 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 2a03bdd7a..4301dff01 100644 --- a/src/agent/service/nodesChainDataGet.ts +++ b/src/agent/service/nodesChainDataGet.ts @@ -2,13 +2,20 @@ import type * as grpc from '@grpc/grpc-js'; import type { Sigchain } from '../../sigchain'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; import type { ClaimIdEncoded } from '../../claims/types'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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, + logger, +}: { + sigchain: Sigchain; + logger: Logger; +}) { return async ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, @@ -38,6 +45,7 @@ function nodesChainDataGet({ sigchain }: { sigchain: Sigchain }) { return; } catch (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 7e5739495..dc709195b 100644 --- a/src/agent/service/nodesClosestLocalNodesGet.ts +++ b/src/agent/service/nodesClosestLocalNodesGet.ts @@ -1,6 +1,7 @@ import type * as grpc from '@grpc/grpc-js'; import type { NodeConnectionManager } from '../../nodes'; import type { NodeId } from '../../nodes/types'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { utils as nodesUtils } from '../../nodes'; import { validateSync, utils as validationUtils } from '../../validation'; @@ -13,8 +14,10 @@ import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; */ function nodesClosestLocalNodesGet({ nodeConnectionManager, + logger, }: { nodeConnectionManager: NodeConnectionManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -54,6 +57,7 @@ function nodesClosestLocalNodesGet({ return; } catch (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 2606606ee..45af67a8d 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -5,6 +5,7 @@ import type { NodeId } from '../../nodes/types'; import type { Sigchain } from '../../sigchain'; import type { KeyManager } from '../../keys'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { utils as claimsUtils, errors as claimsErrors } from '../../claims'; import { utils as nodesUtils } from '../../nodes'; @@ -15,16 +16,16 @@ function nodesCrossSignClaim({ keyManager, nodeManager, sigchain, + logger, }: { 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, true); try { await sigchain.transaction(async (sigchain) => { @@ -149,9 +150,7 @@ 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); @@ -161,8 +160,7 @@ function nodesCrossSignClaim({ }); } 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 2196cceec..438af3775 100644 --- a/src/agent/service/nodesHolePunchMessageSend.ts +++ b/src/agent/service/nodesHolePunchMessageSend.ts @@ -3,6 +3,7 @@ import type { NodeManager, NodeConnectionManager } from '../../nodes'; 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'; @@ -13,10 +14,12 @@ function nodesHolePunchMessageSend({ keyManager, nodeManager, nodeConnectionManager, + logger, }: { keyManager: KeyManager; nodeManager: NodeManager; nodeConnectionManager: NodeConnectionManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -63,6 +66,7 @@ function nodesHolePunchMessageSend({ return; } catch (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 d942da04e..f11a18c95 100644 --- a/src/agent/service/notificationsSend.ts +++ b/src/agent/service/notificationsSend.ts @@ -1,14 +1,17 @@ import type * as grpc from '@grpc/grpc-js'; import type { NotificationsManager } from '../../notifications'; import type * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifications_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { utils as notificationsUtils } from '../../notifications'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function notificationsSend({ notificationsManager, + logger, }: { notificationsManager: NotificationsManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall< @@ -26,6 +29,7 @@ function notificationsSend({ return; } catch (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 1a043f92b..6f4ae9873 100644 --- a/src/agent/service/vaultsGitInfoGet.ts +++ b/src/agent/service/vaultsGitInfoGet.ts @@ -2,6 +2,7 @@ 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 +15,81 @@ import * as agentErrors from '../errors'; function vaultsGitInfoGet({ vaultManager, acl, + logger, connectionInfoGet, }: { vaultManager: VaultManager; acl: ACL; + logger: Logger; connectionInfoGet: ConnectionInfoGet; }) { return async ( call: grpc.ServerWritableStream, ): Promise => { const genWritable = grpcUtils.generatorWritable(call, true); - 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; + try { + const request = call.request; + const vaultMessage = request.getVault(); + if (vaultMessage == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); } - } - // 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( + 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 (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); + if (permissions == null) { + 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( + ); + } + 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, )}`, - ), - ); - 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 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); + } } + 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 8c0d9232f..e96398529 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -3,6 +3,7 @@ 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 Logger from '@matrixai/logger'; import * as nodesUtils from '../../nodes/utils'; import * as grpcErrors from '../../grpc/errors'; import * as grpcUtils from '../../grpc/utils'; @@ -15,86 +16,87 @@ import * as agentErrors from '../errors'; function vaultsGitPackGet({ vaultManager, acl, + logger, connectionInfoGet, }: { vaultManager: VaultManager; acl: ACL; + logger: Logger; connectionInfoGet: ConnectionInfoGet; }) { return async ( call: grpc.ServerDuplexStream, - ) => { + ): Promise => { const genDuplex = grpcUtils.generatorDuplex(call, true); - 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( + 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'); + } + let vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName); + vaultId = vaultId ?? vaultsUtils.decodeVaultId(vaultNameOrId); + if (vaultId == null) { // Throwing permission error to hide information about vaults existence - new vaultsErrors.ErrorVaultsPermissionDenied( + throw new vaultsErrors.ErrorVaultsPermissionDenied( `No permissions found for ${nodeIdEncoded}`, - ), + ); + } + // Checking permissions + const permissions = await acl.getNodePerm(nodeId); + const vaultPerms = permissions?.vaults[vaultId]; + const actionType = validationUtils.parseVaultAction( + meta.get('vaultAction').pop(), ); - 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( + 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), ); - 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); + 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)); + await genDuplex.write(response); + resolve(); + }); + sideBand.on('error', (err) => { + reject(err); + }); + progressStream.write(Buffer.from('0014progress is at 50%\n')); + progressStream.end(); }); - 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(); - }); - 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 acdcfb0b1..bd7cb004b 100644 --- a/src/agent/service/vaultsScan.ts +++ b/src/agent/service/vaultsScan.ts @@ -2,6 +2,7 @@ import type * as grpc from '@grpc/grpc-js'; 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,9 +10,11 @@ import * as grpcUtils from '../../grpc/utils'; function vaultsScan({ vaultManager, + logger, connectionInfoGet, }: { vaultManager: VaultManager; + logger: Logger; connectionInfoGet: ConnectionInfoGet; }) { return async ( @@ -42,6 +45,7 @@ function vaultsScan({ await genWritable.next(null); } catch (e) { await genWritable.throw(e); + logger.error(e); } }; } diff --git a/src/bin/nodes/CommandPing.ts b/src/bin/nodes/CommandPing.ts index 11913011a..3ff6049a1 100644 --- a/src/bin/nodes/CommandPing.ts +++ b/src/bin/nodes/CommandPing.ts @@ -59,7 +59,8 @@ class CommandPing extends CommandPolykey { error = new binErrors.ErrorNodePingFailed( `Failed to resolve node ID ${nodesUtils.encodeNodeId( nodeId, - )} to an address.`, { cause: err }, + )} to an address.`, + { cause: err }, ); } else { throw err; diff --git a/src/claims/errors.ts b/src/claims/errors.ts index 9685201f8..95b03c74a 100644 --- a/src/claims/errors.ts +++ b/src/claims/errors.ts @@ -85,16 +85,12 @@ class ErrorDoublySignedClaimNumSignatures extends ErrorSchemaValidate { exitCode = sysexits.CONFIG; } -class ErrorSinglySignedClaimValidationFailed< - T, -> extends ErrorSchemaValidate { +class ErrorSinglySignedClaimValidationFailed extends ErrorSchemaValidate { static description = 'Claim data does not match schema'; exitCode = sysexits.CONFIG; } -class ErrorDoublySignedClaimValidationFailed< - T, -> extends ErrorSchemaValidate { +class ErrorDoublySignedClaimValidationFailed extends ErrorSchemaValidate { static description = 'Claim data does not match schema'; exitCode = sysexits.CONFIG; } diff --git a/src/client/service/agentLockAll.ts b/src/client/service/agentLockAll.ts index dd80ebf62..6f7eaba76 100644 --- a/src/client/service/agentLockAll.ts +++ b/src/client/service/agentLockAll.ts @@ -1,15 +1,18 @@ import type * as grpc from '@grpc/grpc-js'; 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, + logger, }: { - sessionManager: SessionManager; authenticate: Authenticate; + sessionManager: SessionManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -24,6 +27,7 @@ function agentLockAll({ 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..3ec511381 100644 --- a/src/client/service/gestaltsActionsGetByIdentity.ts +++ b/src/client/service/gestaltsActionsGetByIdentity.ts @@ -3,6 +3,7 @@ import type { Authenticate } from '../types'; import type { GestaltGraph } from '../../gestalts'; 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 { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -11,9 +12,11 @@ import * as permissionsPB from '../../proto/js/polykey/v1/permissions/permission function gestaltsActionsGetByIdentity({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -55,6 +58,7 @@ function gestaltsActionsGetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsGetByNode.ts b/src/client/service/gestaltsActionsGetByNode.ts index f4bcd4d5a..77b6c54fd 100644 --- a/src/client/service/gestaltsActionsGetByNode.ts +++ b/src/client/service/gestaltsActionsGetByNode.ts @@ -3,6 +3,7 @@ import type { Authenticate } from '../types'; import type { NodeId } from '../../nodes/types'; import type { GestaltGraph } from '../../gestalts'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -11,9 +12,11 @@ import * as permissionsPB from '../../proto/js/polykey/v1/permissions/permission function gestaltsActionsGetByNode({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -47,6 +50,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..34140fec9 100644 --- a/src/client/service/gestaltsActionsSetByIdentity.ts +++ b/src/client/service/gestaltsActionsSetByIdentity.ts @@ -4,6 +4,7 @@ import type { GestaltGraph } from '../../gestalts'; 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 type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -12,9 +13,11 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsActionsSetByIdentity({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -56,6 +59,7 @@ function gestaltsActionsSetByIdentity({ 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..0c801c350 100644 --- a/src/client/service/gestaltsActionsSetByNode.ts +++ b/src/client/service/gestaltsActionsSetByNode.ts @@ -4,6 +4,7 @@ import type { GestaltGraph } from '../../gestalts'; 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 type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -12,9 +13,11 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsActionsSetByNode({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -43,6 +46,7 @@ function gestaltsActionsSetByNode({ 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..9ab5ac61e 100644 --- a/src/client/service/gestaltsActionsUnsetByIdentity.ts +++ b/src/client/service/gestaltsActionsUnsetByIdentity.ts @@ -4,6 +4,7 @@ import type { GestaltGraph } from '../../gestalts'; 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 type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -12,9 +13,11 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsActionsUnsetByIdentity({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -56,6 +59,7 @@ function gestaltsActionsUnsetByIdentity({ 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..795f9c4fc 100644 --- a/src/client/service/gestaltsActionsUnsetByNode.ts +++ b/src/client/service/gestaltsActionsUnsetByNode.ts @@ -4,6 +4,7 @@ import type { GestaltGraph } from '../../gestalts'; 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 type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -12,9 +13,11 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function gestaltsActionsUnsetByNode({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -43,6 +46,7 @@ function gestaltsActionsUnsetByNode({ 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..c8e515ab7 100644 --- a/src/client/service/gestaltsDiscoveryByIdentity.ts +++ b/src/client/service/gestaltsDiscoveryByIdentity.ts @@ -3,6 +3,7 @@ import type { Authenticate } from '../types'; import type { Discovery } from '../../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..26e575c51 100644 --- a/src/client/service/gestaltsDiscoveryByNode.ts +++ b/src/client/service/gestaltsDiscoveryByNode.ts @@ -3,6 +3,7 @@ import type { Authenticate } from '../types'; import type { Discovery } from '../../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..5f2257a82 100644 --- a/src/client/service/gestaltsGestaltGetByIdentity.ts +++ b/src/client/service/gestaltsGestaltGetByIdentity.ts @@ -3,6 +3,7 @@ import type { Authenticate } from '../types'; import type { GestaltGraph } from '../../gestalts'; 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 { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -11,9 +12,11 @@ import * as gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; function gestaltsGestaltGetByIdentity({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -53,6 +56,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..a0ea6f03c 100644 --- a/src/client/service/gestaltsGestaltGetByNode.ts +++ b/src/client/service/gestaltsGestaltGetByNode.ts @@ -3,6 +3,7 @@ import type { Authenticate } from '../types'; import type { NodeId } from '../../nodes/types'; import type { GestaltGraph } from '../../gestalts'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -11,9 +12,11 @@ import * as gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; function gestaltsGestaltGetByNode({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -46,6 +49,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 6f3c1c9ea..305cd3b7d 100644 --- a/src/client/service/gestaltsGestaltList.ts +++ b/src/client/service/gestaltsGestaltList.ts @@ -3,15 +3,18 @@ import type { Authenticate } from '../types'; import type { GestaltGraph } from '../../gestalts'; import type { Gestalt } from '../../gestalts/types'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import * as gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; function gestaltsGestaltList({ authenticate, gestaltGraph, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, @@ -31,6 +34,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..df7b60dc4 100644 --- a/src/client/service/gestaltsGestaltTrustByIdentity.ts +++ b/src/client/service/gestaltsGestaltTrustByIdentity.ts @@ -4,6 +4,7 @@ import type { GestaltGraph } from '../../gestalts'; import type { IdentityId, ProviderId } from '../../identities/types'; import type { Discovery } from '../../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 +15,12 @@ function gestaltsGestaltTrustByIdentity({ authenticate, gestaltGraph, discovery, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; discovery: Discovery; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -70,6 +73,7 @@ function gestaltsGestaltTrustByIdentity({ 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..8ebe7660b 100644 --- a/src/client/service/gestaltsGestaltTrustByNode.ts +++ b/src/client/service/gestaltsGestaltTrustByNode.ts @@ -4,6 +4,7 @@ import type { GestaltGraph } from '../../gestalts'; import type { Discovery } from '../../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 +16,12 @@ function gestaltsGestaltTrustByNode({ authenticate, gestaltGraph, discovery, + logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; discovery: Discovery; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -58,6 +61,7 @@ function gestaltsGestaltTrustByNode({ 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 c80378790..e2e39162f 100644 --- a/src/client/service/identitiesAuthenticate.ts +++ b/src/client/service/identitiesAuthenticate.ts @@ -2,6 +2,7 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { IdentitiesManager } from '../../identities'; import type { ProviderId } from '../../identities/types'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { errors as identitiesErrors } from '../../identities'; import { validateSync, utils as validationUtils } from '../../validation'; @@ -9,11 +10,13 @@ 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< @@ -70,6 +73,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 fa2ca756f..d344c14a6 100644 --- a/src/client/service/identitiesAuthenticatedGet.ts +++ b/src/client/service/identitiesAuthenticatedGet.ts @@ -2,6 +2,7 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { IdentitiesManager } from '../../identities'; 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< @@ -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..2367998df 100644 --- a/src/client/service/identitiesClaim.ts +++ b/src/client/service/identitiesClaim.ts @@ -4,6 +4,7 @@ import type KeyManager from '../../keys/KeyManager'; import type { Sigchain } from '../../sigchain'; import type { IdentitiesManager } from '../../identities'; import type { IdentityId, ProviderId } from '../../identities/types'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { utils as claimsUtils } from '../../claims'; import { utils as nodesUtils } from '../../nodes'; @@ -16,15 +17,17 @@ 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, + logger, }: { + authenticate: Authenticate; identitiesManager: IdentitiesManager; sigchain: Sigchain; keyManager: KeyManager; - authenticate: Authenticate; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -80,6 +83,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 865616d06..f232e3a4d 100644 --- a/src/client/service/identitiesInfoConnectedGet.ts +++ b/src/client/service/identitiesInfoConnectedGet.ts @@ -6,6 +6,7 @@ import type { 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< @@ -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 400367140..31a8139c8 100644 --- a/src/client/service/identitiesInfoGet.ts +++ b/src/client/service/identitiesInfoGet.ts @@ -6,6 +6,7 @@ import type { 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< @@ -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..8fa533a9c 100644 --- a/src/client/service/identitiesProvidersList.ts +++ b/src/client/service/identitiesProvidersList.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { IdentitiesManager } from '../../identities'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..69bba5775 100644 --- a/src/client/service/identitiesTokenDelete.ts +++ b/src/client/service/identitiesTokenDelete.ts @@ -3,17 +3,20 @@ import type { Authenticate } from '../types'; import type { IdentitiesManager } from '../../identities'; 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 { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function identitiesTokenDelete({ - identitiesManager, authenticate, + identitiesManager, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -47,6 +50,7 @@ function identitiesTokenDelete({ 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..cb7987156 100644 --- a/src/client/service/identitiesTokenGet.ts +++ b/src/client/service/identitiesTokenGet.ts @@ -2,17 +2,20 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { IdentitiesManager } from '../../identities'; import type { IdentityId, ProviderId } from '../../identities/types'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; function identitiesTokenGet({ - identitiesManager, authenticate, + identitiesManager, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -47,6 +50,7 @@ function identitiesTokenGet({ 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..cb532d4c1 100644 --- a/src/client/service/identitiesTokenPut.ts +++ b/src/client/service/identitiesTokenPut.ts @@ -3,17 +3,20 @@ import type { Authenticate } from '../types'; import type { IdentitiesManager } from '../../identities'; import type { IdentityId, ProviderId, TokenData } from '../../identities/types'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function identitiesTokenPut({ - identitiesManager, authenticate, + identitiesManager, + logger, }: { - identitiesManager: IdentitiesManager; authenticate: Authenticate; + identitiesManager: IdentitiesManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall< @@ -52,6 +55,7 @@ function identitiesTokenPut({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; diff --git a/src/client/service/keysCertsChainGet.ts b/src/client/service/keysCertsChainGet.ts index 792b86916..b62c85783 100644 --- a/src/client/service/keysCertsChainGet.ts +++ b/src/client/service/keysCertsChainGet.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { KeyManager } from '../../keys'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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, @@ -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..6d63cfba8 100644 --- a/src/client/service/keysCertsGet.ts +++ b/src/client/service/keysCertsGet.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { KeyManager } from '../../keys'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..05e68e066 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 type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..2c84444fb 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 type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..c2d88acca 100644 --- a/src/client/service/keysKeyPairRenew.ts +++ b/src/client/service/keysKeyPairRenew.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { KeyManager } from '../../keys'; import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..82e73277e 100644 --- a/src/client/service/keysKeyPairReset.ts +++ b/src/client/service/keysKeyPairReset.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { KeyManager } from '../../keys'; import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..9f20b410b 100644 --- a/src/client/service/keysKeyPairRoot.ts +++ b/src/client/service/keysKeyPairRoot.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { KeyManager } from '../../keys'; import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..21ad66425 100644 --- a/src/client/service/keysPasswordChange.ts +++ b/src/client/service/keysPasswordChange.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { KeyManager } from '../../keys'; import type * as sessionsPB from '../../proto/js/polykey/v1/sessions/sessions_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..14f722a0c 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 type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..26918bc3d 100644 --- a/src/client/service/keysVerify.ts +++ b/src/client/service/keysVerify.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { KeyManager } from '../../keys'; import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; 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..7cbfb739f 100644 --- a/src/client/service/nodesAdd.ts +++ b/src/client/service/nodesAdd.ts @@ -4,6 +4,7 @@ import type { NodeManager } from '../../nodes'; 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 type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -15,11 +16,13 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; * of the passed ID or host/port. */ function nodesAdd({ - nodeManager, authenticate, + nodeManager, + logger, }: { - nodeManager: NodeManager; authenticate: Authenticate; + nodeManager: NodeManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -60,6 +63,7 @@ function nodesAdd({ 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..b82731c05 100644 --- a/src/client/service/nodesClaim.ts +++ b/src/client/service/nodesClaim.ts @@ -4,6 +4,7 @@ import type { NodeManager } from '../../nodes'; import type { NodeId } from '../../nodes/types'; import type { NotificationsManager } from '../../notifications'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -15,13 +16,15 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; * other node and host node. */ function nodesClaim({ + authenticate, nodeManager, notificationsManager, - authenticate, + logger, }: { + authenticate: Authenticate; nodeManager: NodeManager; notificationsManager: NotificationsManager; - authenticate: Authenticate; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -65,6 +68,7 @@ function nodesClaim({ 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..b8cb887db 100644 --- a/src/client/service/nodesFind.ts +++ b/src/client/service/nodesFind.ts @@ -2,6 +2,7 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { NodeConnectionManager } from '../../nodes'; import type { NodeId } from '../../nodes/types'; +import type Logger from '@matrixai/logger'; import { utils as nodesUtils } from '../../nodes'; import { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; @@ -14,11 +15,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 +56,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..2356f2072 100644 --- a/src/client/service/nodesPing.ts +++ b/src/client/service/nodesPing.ts @@ -3,6 +3,7 @@ import type { Authenticate } from '../types'; import type { NodeManager } from '../../nodes'; 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 { utils as grpcUtils } from '../../grpc'; import { validateSync, utils as validationUtils } from '../../validation'; import { matchSync } from '../../utils'; @@ -12,11 +13,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 +50,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..7d2ba80cc 100644 --- a/src/client/service/notificationsClear.ts +++ b/src/client/service/notificationsClear.ts @@ -1,15 +1,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { NotificationsManager } from '../../notifications'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function notificationsClear({ - notificationsManager, authenticate, + notificationsManager, + logger, }: { - notificationsManager: NotificationsManager; authenticate: Authenticate; + notificationsManager: NotificationsManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -24,6 +27,7 @@ function notificationsClear({ 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..f8bccc692 100644 --- a/src/client/service/notificationsRead.ts +++ b/src/client/service/notificationsRead.ts @@ -1,15 +1,18 @@ import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { NotificationsManager } from '../../notifications'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifications_pb'; function notificationsRead({ - notificationsManager, authenticate, + notificationsManager, + logger, }: { - notificationsManager: NotificationsManager; authenticate: Authenticate; + notificationsManager: NotificationsManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -65,6 +68,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..c30512611 100644 --- a/src/client/service/notificationsSend.ts +++ b/src/client/service/notificationsSend.ts @@ -3,6 +3,7 @@ import type { Authenticate } from '../types'; import type { NotificationsManager } from '../../notifications'; import type { NodeId } from '../../nodes/types'; import type * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifications_pb'; +import type Logger from '@matrixai/logger'; import { utils as grpcUtils } from '../../grpc'; import { utils as notificationsUtils } from '../../notifications'; import { validateSync, utils as validationUtils } from '../../validation'; @@ -10,11 +11,13 @@ 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 +53,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..75b6dcf56 100644 --- a/src/client/service/vaultsClone.ts +++ b/src/client/service/vaultsClone.ts @@ -1,6 +1,7 @@ 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 +11,11 @@ import * as vaultsUtils from '../../vaults/utils'; function vaultsClone({ authenticate, vaultManager, + logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -46,6 +49,7 @@ function vaultsClone({ 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..74224733b 100644 --- a/src/client/service/vaultsCreate.ts +++ b/src/client/service/vaultsCreate.ts @@ -3,16 +3,19 @@ import type { VaultId, VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; 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, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -31,6 +34,7 @@ function vaultsCreate({ 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..0f7aa01e7 100644 --- a/src/client/service/vaultsDelete.ts +++ b/src/client/service/vaultsDelete.ts @@ -3,16 +3,19 @@ import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; 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, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -32,6 +35,7 @@ function vaultsDelete({ 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 c35f51eea..794c44909 100644 --- a/src/client/service/vaultsList.ts +++ b/src/client/service/vaultsList.ts @@ -2,16 +2,19 @@ import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; 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, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, @@ -34,6 +37,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 02b35a6f8..6d720e825 100644 --- a/src/client/service/vaultsLog.ts +++ b/src/client/service/vaultsLog.ts @@ -1,6 +1,7 @@ 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,11 +9,13 @@ import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; import * as validationUtils from '../../validation/utils'; function vaultsLog({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, @@ -52,6 +55,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 bb2b24dc1..8dd0866c3 100644 --- a/src/client/service/vaultsPermissionGet.ts +++ b/src/client/service/vaultsPermissionGet.ts @@ -5,6 +5,7 @@ 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,10 +17,12 @@ function vaultsPermissionGet({ authenticate, vaultManager, acl, + logger, }: { authenticate: Authenticate; vaultManager: VaultManager; acl: ACL; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, @@ -57,8 +60,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..f19ec7da3 100644 --- a/src/client/service/vaultsPermissionSet.ts +++ b/src/client/service/vaultsPermissionSet.ts @@ -6,6 +6,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 +15,19 @@ 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, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; gestaltGraph: GestaltGraph; acl: ACL; notificationsManager: NotificationsManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -74,6 +77,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..cd9c0ee9e 100644 --- a/src/client/service/vaultsPermissionUnset.ts +++ b/src/client/service/vaultsPermissionUnset.ts @@ -4,6 +4,7 @@ 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 +12,17 @@ import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsPermissionUnset({ - vaultManager, authenticate, + vaultManager, gestaltGraph, acl, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; gestaltGraph: GestaltGraph; acl: ACL; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -73,6 +76,7 @@ function vaultsPermissionUnset({ 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..821e3179a 100644 --- a/src/client/service/vaultsPull.ts +++ b/src/client/service/vaultsPull.ts @@ -2,6 +2,7 @@ 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 +12,11 @@ import * as vaultsUtils from '../../vaults/utils'; function vaultsPull({ authenticate, vaultManager, + logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -58,6 +61,7 @@ function vaultsPull({ 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..27276c1aa 100644 --- a/src/client/service/vaultsRename.ts +++ b/src/client/service/vaultsRename.ts @@ -1,6 +1,7 @@ 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 +9,13 @@ import * as vaultsUtils from '../../vaults/utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsRename({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -37,6 +40,7 @@ function vaultsRename({ 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 0ed5ebbbe..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,11 +11,13 @@ 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, @@ -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..6332c1442 100644 --- a/src/client/service/vaultsSecretsDelete.ts +++ b/src/client/service/vaultsSecretsDelete.ts @@ -2,6 +2,7 @@ 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 +10,13 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsDelete({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -40,6 +43,7 @@ function vaultsSecretsDelete({ 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..d502d9808 100644 --- a/src/client/service/vaultsSecretsEdit.ts +++ b/src/client/service/vaultsSecretsEdit.ts @@ -2,6 +2,7 @@ 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 +10,13 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsEdit({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -46,6 +49,7 @@ function vaultsSecretsEdit({ 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..bd3c3a330 100644 --- a/src/client/service/vaultsSecretsGet.ts +++ b/src/client/service/vaultsSecretsGet.ts @@ -2,6 +2,7 @@ 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 +10,13 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; function vaultsSecretsGet({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -43,6 +46,7 @@ function vaultsSecretsGet({ 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 db71fc128..c9732edbf 100644 --- a/src/client/service/vaultsSecretsList.ts +++ b/src/client/service/vaultsSecretsList.ts @@ -3,17 +3,20 @@ import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; 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, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerWritableStream, @@ -42,6 +45,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..3753571c7 100644 --- a/src/client/service/vaultsSecretsMkdir.ts +++ b/src/client/service/vaultsSecretsMkdir.ts @@ -2,6 +2,7 @@ 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 +10,13 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsMkdir({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -42,6 +45,7 @@ function vaultsSecretsMkdir({ 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..b264631f9 100644 --- a/src/client/service/vaultsSecretsNew.ts +++ b/src/client/service/vaultsSecretsNew.ts @@ -2,6 +2,7 @@ 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 +10,13 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsNew({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -41,6 +44,7 @@ function vaultsSecretsNew({ 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..36fd2b3af 100644 --- a/src/client/service/vaultsSecretsNewDir.ts +++ b/src/client/service/vaultsSecretsNewDir.ts @@ -3,6 +3,7 @@ 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 +11,15 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsNewDir({ - vaultManager, authenticate, + vaultManager, fs, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; fs: FileSystem; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -43,6 +46,7 @@ function vaultsSecretsNewDir({ 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..ceeb7160e 100644 --- a/src/client/service/vaultsSecretsRename.ts +++ b/src/client/service/vaultsSecretsRename.ts @@ -2,6 +2,7 @@ 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 +10,13 @@ import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsRename({ - vaultManager, authenticate, + vaultManager, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -46,6 +49,7 @@ function vaultsSecretsRename({ 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..ab03c57e4 100644 --- a/src/client/service/vaultsSecretsStat.ts +++ b/src/client/service/vaultsSecretsStat.ts @@ -1,6 +1,7 @@ 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 +11,11 @@ import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; function vaultsSecretsStat({ authenticate, vaultManager, + logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -39,6 +42,7 @@ function vaultsSecretsStat({ 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..fcb32a2fe 100644 --- a/src/client/service/vaultsVersion.ts +++ b/src/client/service/vaultsVersion.ts @@ -1,17 +1,20 @@ 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, + logger, }: { - vaultManager: VaultManager; authenticate: Authenticate; + vaultManager: VaultManager; + logger: Logger; }) { return async ( call: grpc.ServerUnaryCall, @@ -52,6 +55,7 @@ function vaultsVersion({ return; } catch (e) { callback(grpcUtils.fromError(e)); + logger.error(e); return; } }; 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/grpc/GRPCClient.ts b/src/grpc/GRPCClient.ts index b705e9aa5..22a7c65e5 100644 --- a/src/grpc/GRPCClient.ts +++ b/src/grpc/GRPCClient.ts @@ -151,7 +151,8 @@ abstract class GRPCClient { `Failed GRPC server certificate verification connecting to ${address}`, ); const e_ = new grpcErrors.ErrorGRPCClientVerification( - `${e.name}: ${e.message}`,{ + `${e.name}: ${e.message}`, + { data: e.data, cause: e, }, diff --git a/src/grpc/GRPCServer.ts b/src/grpc/GRPCServer.ts index 2c7edf11b..b7a0ac84c 100644 --- a/src/grpc/GRPCServer.ts +++ b/src/grpc/GRPCServer.ts @@ -100,7 +100,8 @@ class GRPCServer { `Failed GRPC client certificate verification connecting from ${address}`, ); const e_ = new grpcErrors.ErrorGRPCServerVerification( - `${e.name}: ${e.message}`, { + `${e.name}: ${e.message}`, + { data: e.data, cause: e, }, diff --git a/src/grpc/utils/utils.ts b/src/grpc/utils/utils.ts index b75a6d21e..7db50484c 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -162,7 +162,10 @@ function getServerSession(call: ServerSurfaceCall): Http2Session { * 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, sensitive: boolean = false): ServerStatusResponse { +function fromError( + error: Error, + sensitive: boolean = false, +): ServerStatusResponse { const metadata = new grpc.Metadata(); if (sensitive) { metadata.set('error', JSON.stringify(error, sensitiveReplacer)); @@ -188,10 +191,7 @@ 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' && - errorData != null - ) { + if (key === 'UNKNOWN' && errorData != null) { const error: Error = JSON.parse(errorData, reviver); return new errors.ErrorPolykeyRemote(error.message, { cause: error }); } else { @@ -214,7 +214,7 @@ function toError(e: ServiceError): errors.ErrorPolykey { * Polykey errors are handled by their inbuilt `toJSON` method , so this only * serialises other errors */ - function replacer(key: string, value: any): any { +function replacer(key: string, value: any): any { if (value instanceof AbstractError) { // Include the standard properties from an AbstractError return { @@ -226,8 +226,8 @@ function toError(e: ServiceError): errors.ErrorPolykey { data: value.data, cause: value.cause, 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) @@ -236,8 +236,8 @@ function toError(e: ServiceError): errors.ErrorPolykey { data: { message: value.message, stack: value.stack, - } - } + }, + }; } else { // If it's not an error then just leave as is return value; @@ -262,13 +262,13 @@ function sensitiveReplacer(key: string, value: any) { * Allows these errors to be reconstructed from GRPC metadata */ const otherErrors = { - 'Error': Error, - 'EvalError': EvalError, - 'RangeError': RangeError, - 'ReferenceError': ReferenceError, - 'SyntaxError': SyntaxError, - 'TypeError': TypeError, - 'URIError': URIError + Error: Error, + EvalError: EvalError, + RangeError: RangeError, + ReferenceError: ReferenceError, + SyntaxError: SyntaxError, + TypeError: TypeError, + URIError: URIError, }; /** @@ -280,17 +280,18 @@ const otherErrors = { */ 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') { + if ( + typeof value === 'object' && + typeof value.type === 'string' && + typeof value.data === 'object' + ) { const message = value.data.message ?? ''; if (value.type in errors) { - const error = new errors[value.type]( - message, - { - timestamp: value.data.timestamp, - data: value.data.data, - cause: value.data.cause, - }, - ); + const error = new errors[value.type](message, { + timestamp: value.data.timestamp, + data: value.data.data, + cause: value.data.cause, + }); error.exitCode = value.data.exitCode; if (value.data.stack) { error.stack = value.data.stack; diff --git a/src/identities/errors.ts b/src/identities/errors.ts index dece95ffc..40ade2ceb 100644 --- a/src/identities/errors.ts +++ b/src/identities/errors.ts @@ -33,7 +33,8 @@ class ErrorProviderAuthentication extends ErrorIdentities { } class ErrorProviderUnauthenticated extends ErrorIdentities { - static description = 'Provider has not been authenticated or access token is expired or invalid'; + static description = + 'Provider has not been authenticated or access token is expired or invalid'; exitCode = sysexits.NOPERM; } diff --git a/src/identities/providers/github/GitHubProvider.ts b/src/identities/providers/github/GitHubProvider.ts index 122122931..8fd0a79fe 100644 --- a/src/identities/providers/github/GitHubProvider.ts +++ b/src/identities/providers/github/GitHubProvider.ts @@ -120,7 +120,8 @@ class GitHubProvider extends Provider { data = await response.json(); } catch (e) { throw new identitiesErrors.ErrorProviderAuthentication( - 'Provider access token response is not valid JSON', { cause: e }, + 'Provider access token response is not valid JSON', + { cause: e }, ); } if (data.error) { diff --git a/src/network/utils.ts b/src/network/utils.ts index f97f71ef9..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, { cause: e }); + throw new networkErrors.ErrorHostnameResolutionFailed(e.message, { + cause: e, + }); } // Returns an array of [ resolved address, family (4 or 6) ] return resolvedHost[0] as Host; diff --git a/src/nodes/NodeConnection.ts b/src/nodes/NodeConnection.ts index d81ac9721..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(e.message, { cause: e }); + throw new nodesErrors.ErrorNodeConnectionTimeout(e.message, { + cause: e, + }); } throw e; } diff --git a/src/notifications/errors.ts b/src/notifications/errors.ts index 3a9ca102f..028862e50 100644 --- a/src/notifications/errors.ts +++ b/src/notifications/errors.ts @@ -47,9 +47,7 @@ class ErrorNotificationsGeneralInvalid extends ErrorSchemaValidate { exitCode = sysexits.USAGE; } -class ErrorNotificationsGestaltInviteInvalid< - T, -> extends ErrorSchemaValidate { +class ErrorNotificationsGestaltInviteInvalid extends ErrorSchemaValidate { static description = 'Invalid notification data'; exitCode = sysexits.USAGE; } diff --git a/src/notifications/utils.ts b/src/notifications/utils.ts index 0f55a6620..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(err.message, { cause: err }); + throw new notificationsErrors.ErrorNotificationsParse(err.message, { + cause: err, + }); } } } diff --git a/src/status/Status.ts b/src/status/Status.ts index fbee3edce..01647736c 100644 --- a/src/status/Status.ts +++ b/src/status/Status.ts @@ -145,7 +145,9 @@ class Status { try { statusInfo = JSON.parse(statusData, this.statusReviver); } catch (e) { - throw new statusErrors.ErrorStatusParse('JSON parsing failed', {cause: e}); + throw new statusErrors.ErrorStatusParse('JSON parsing failed', { + cause: e, + }); } if (!statusUtils.statusValidate(statusInfo)) { throw new statusErrors.ErrorStatusParse( @@ -246,7 +248,9 @@ class Status { try { statusInfo = JSON.parse(statusData, this.statusReviver); } catch (e) { - throw new statusErrors.ErrorStatusParse('JSON parsing failed', { cause: e }); + throw new statusErrors.ErrorStatusParse('JSON parsing failed', { + cause: e, + }); } if (!statusUtils.statusValidate(statusInfo)) { throw new statusErrors.ErrorStatusParse( diff --git a/src/vaults/VaultInternal.ts b/src/vaults/VaultInternal.ts index c7f60829b..34597b034 100644 --- a/src/vaults/VaultInternal.ts +++ b/src/vaults/VaultInternal.ts @@ -376,7 +376,9 @@ class VaultInternal { e instanceof git.Errors.NotFoundError || e instanceof git.Errors.CommitNotFetchedError ) { - throw new vaultsErrors.ErrorVaultReferenceMissing(e.message, { cause: e }); + throw new vaultsErrors.ErrorVaultReferenceMissing(e.message, { + cause: e, + }); } throw e; } @@ -551,7 +553,9 @@ class VaultInternal { if (err instanceof git.Errors.SmartHttpError && error) { throw error; } else if (err instanceof git.Errors.MergeNotSupportedError) { - throw new vaultsErrors.ErrorVaultsMergeConflict(err.message, { cause: err }); + throw new vaultsErrors.ErrorVaultsMergeConflict(err.message, { + cause: err, + }); } throw err; } diff --git a/tests/agent/service/nodesCrossSignClaim.test.ts b/tests/agent/service/nodesCrossSignClaim.test.ts index 0c3a1da7a..5b3f6c53e 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'; @@ -78,6 +78,7 @@ describe('nodesCrossSignClaim', () => { keyManager: pkAgent.keyManager, nodeManager: pkAgent.nodeManager, sigchain: pkAgent.sigchain, + logger, }), }; grpcServer = new GRPCServer({ logger }); @@ -204,9 +205,7 @@ 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); @@ -226,9 +225,7 @@ 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); diff --git a/tests/agent/service/notificationsSend.test.ts b/tests/agent/service/notificationsSend.test.ts index a0eb81ffa..3732b407e 100644 --- a/tests/agent/service/notificationsSend.test.ts +++ b/tests/agent/service/notificationsSend.test.ts @@ -137,6 +137,7 @@ describe('notificationsSend', () => { const agentService = { notificationsSend: notificationsSend({ notificationsManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); 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/service/agentLockAll.test.ts b/tests/client/service/agentLockAll.test.ts index 21a533dd6..4ae0d6665 100644 --- a/tests/client/service/agentLockAll.test.ts +++ b/tests/client/service/agentLockAll.test.ts @@ -75,6 +75,7 @@ describe('agentLockall', () => { agentLockAll: agentLockAll({ authenticate, sessionManager, + logger, }), }; grpcServer = new GRPCServer({ 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..09dfaae3b 100644 --- a/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts +++ b/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts @@ -72,14 +72,17 @@ describe('gestaltsActionsByIdentity', () => { gestaltsActionsSetByIdentity: gestaltsActionsSetByIdentity({ authenticate, gestaltGraph, + logger, }), gestaltsActionsGetByIdentity: gestaltsActionsGetByIdentity({ authenticate, gestaltGraph, + logger, }), gestaltsActionsUnsetByIdentity: gestaltsActionsUnsetByIdentity({ authenticate, gestaltGraph, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts b/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts index 5eb2e40bf..cfec8dfda 100644 --- a/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts +++ b/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts @@ -66,14 +66,17 @@ describe('gestaltsActionsByNode', () => { gestaltsActionsSetByNode: gestaltsActionsSetByNode({ authenticate, gestaltGraph, + logger, }), gestaltsActionsGetByNode: gestaltsActionsGetByNode({ authenticate, gestaltGraph, + logger, }), gestaltsActionsUnsetByNode: gestaltsActionsUnsetByNode({ authenticate, gestaltGraph, + logger, }), }; 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..cddc5af3f 100644 --- a/tests/client/service/gestaltsGestaltGetByIdentity.test.ts +++ b/tests/client/service/gestaltsGestaltGetByIdentity.test.ts @@ -89,6 +89,7 @@ describe('gestaltsGestaltGetByIdentity', () => { gestaltsGestaltGetByIdentity: gestaltsGestaltGetByIdentity({ authenticate, gestaltGraph, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltGetByNode.test.ts b/tests/client/service/gestaltsGestaltGetByNode.test.ts index ebff5bf7d..2a5848203 100644 --- a/tests/client/service/gestaltsGestaltGetByNode.test.ts +++ b/tests/client/service/gestaltsGestaltGetByNode.test.ts @@ -86,6 +86,7 @@ describe('gestaltsGestaltGetByNode', () => { gestaltsGestaltGetByNode: gestaltsGestaltGetByNode({ authenticate, gestaltGraph, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltList.test.ts b/tests/client/service/gestaltsGestaltList.test.ts index 6b714e073..c724124d7 100644 --- a/tests/client/service/gestaltsGestaltList.test.ts +++ b/tests/client/service/gestaltsGestaltList.test.ts @@ -92,6 +92,7 @@ describe('gestaltsGestaltList', () => { gestaltsGestaltList: gestaltsGestaltList({ authenticate, gestaltGraph, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts b/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts index 8bd0a749e..74ecff0e3 100644 --- a/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts +++ b/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts @@ -227,6 +227,7 @@ describe('gestaltsGestaltTrustByIdentity', () => { authenticate, gestaltGraph, discovery, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltTrustByNode.test.ts b/tests/client/service/gestaltsGestaltTrustByNode.test.ts index ccc7c827d..7cb297e67 100644 --- a/tests/client/service/gestaltsGestaltTrustByNode.test.ts +++ b/tests/client/service/gestaltsGestaltTrustByNode.test.ts @@ -225,6 +225,7 @@ describe('gestaltsGestaltTrustByNode', () => { authenticate, gestaltGraph, discovery, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/identitiesAuthenticate.test.ts b/tests/client/service/identitiesAuthenticate.test.ts index fb3c2a9ff..73bce737e 100644 --- a/tests/client/service/identitiesAuthenticate.test.ts +++ b/tests/client/service/identitiesAuthenticate.test.ts @@ -56,6 +56,7 @@ describe('identitiesAuthenticate', () => { identitiesAuthenticate: identitiesAuthenticate({ authenticate, identitiesManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); 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..6259afaea 100644 --- a/tests/client/service/identitiesClaim.test.ts +++ b/tests/client/service/identitiesClaim.test.ts @@ -148,6 +148,7 @@ describe('identitiesClaim', () => { identitiesManager, sigchain, keyManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/identitiesInfoConnectedGet.test.ts b/tests/client/service/identitiesInfoConnectedGet.test.ts index 0dce4a1bb..300567584 100644 --- a/tests/client/service/identitiesInfoConnectedGet.test.ts +++ b/tests/client/service/identitiesInfoConnectedGet.test.ts @@ -52,6 +52,7 @@ describe('identitiesInfoConnectedGet', () => { identitiesInfoConnectedGet: identitiesInfoConnectedGet({ authenticate, identitiesManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); 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..f26eb192b 100644 --- a/tests/client/service/identitiesTokenPutDeleteGet.test.ts +++ b/tests/client/service/identitiesTokenPutDeleteGet.test.ts @@ -56,14 +56,17 @@ describe('identitiesTokenPutDeleteGet', () => { identitiesTokenPut: identitiesTokenPut({ authenticate, identitiesManager, + logger, }), identitiesTokenGet: identitiesTokenGet({ authenticate, identitiesManager, + logger, }), identitiesTokenDelete: identitiesTokenDelete({ authenticate, identitiesManager, + logger, }), }; 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..550f793dd 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 }); diff --git a/tests/client/service/keysKeyPairReset.test.ts b/tests/client/service/keysKeyPairReset.test.ts index 155d6071e..754d80075 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 }); 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..168e64a34 100644 --- a/tests/client/service/nodesAdd.test.ts +++ b/tests/client/service/nodesAdd.test.ts @@ -116,6 +116,7 @@ describe('nodesAdd', () => { nodesAdd: nodesAdd({ authenticate, nodeManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/nodesClaim.test.ts b/tests/client/service/nodesClaim.test.ts index 07d41e500..2686ce3ed 100644 --- a/tests/client/service/nodesClaim.test.ts +++ b/tests/client/service/nodesClaim.test.ts @@ -159,6 +159,7 @@ describe('nodesClaim', () => { authenticate, nodeManager, notificationsManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/nodesFind.test.ts b/tests/client/service/nodesFind.test.ts index 1197638f5..0297bccbd 100644 --- a/tests/client/service/nodesFind.test.ts +++ b/tests/client/service/nodesFind.test.ts @@ -110,8 +110,9 @@ describe('nodesFind', () => { await nodeConnectionManager.start(); const clientService = { nodesFind: nodesFind({ - nodeConnectionManager, authenticate, + nodeConnectionManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/nodesPing.test.ts b/tests/client/service/nodesPing.test.ts index 0bfcabc97..43dddcba1 100644 --- a/tests/client/service/nodesPing.test.ts +++ b/tests/client/service/nodesPing.test.ts @@ -121,6 +121,7 @@ describe('nodesPing', () => { nodesPing: nodesPing({ authenticate, nodeManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/notificationsClear.test.ts b/tests/client/service/notificationsClear.test.ts index 2fab2e233..62cc7ce63 100644 --- a/tests/client/service/notificationsClear.test.ts +++ b/tests/client/service/notificationsClear.test.ts @@ -135,6 +135,7 @@ describe('notificationsClear', () => { notificationsClear: notificationsClear({ authenticate, notificationsManager, + logger, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/notificationsRead.test.ts b/tests/client/service/notificationsRead.test.ts index 1b77af1a3..393943f5e 100644 --- a/tests/client/service/notificationsRead.test.ts +++ b/tests/client/service/notificationsRead.test.ts @@ -209,6 +209,7 @@ describe('notificationsRead', () => { notificationsRead: notificationsRead({ authenticate, notificationsManager, + logger, }), }; 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/grpc/utils.test.ts b/tests/grpc/utils.test.ts index b2390e2fa..496f6553b 100644 --- a/tests/grpc/utils.test.ts +++ b/tests/grpc/utils.test.ts @@ -105,7 +105,9 @@ describe('GRPC utils', () => { const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge(challenge); const stream = serverStream(messageTo); - await expect(() => stream.next()).rejects.toThrow(errors.ErrorPolykeyRemote); + 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(); @@ -276,7 +278,9 @@ describe('GRPC utils', () => { const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); await genDuplex.write(messageTo); - await expect(() => genDuplex.read()).rejects.toThrow(errors.ErrorPolykeyRemote); + await expect(() => genDuplex.read()).rejects.toThrow( + errors.ErrorPolykeyRemote, + ); expect(genDuplex.stream.destroyed).toBe(true); expect(genDuplex.stream.getPeer()).toBe(`127.0.0.1:${port}`); }); @@ -316,7 +320,7 @@ describe('GRPC utils', () => { message: '', code: 2, details: '', - metadata: serialised + metadata: serialised, }); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); @@ -341,7 +345,7 @@ describe('GRPC utils', () => { message: '', code: 2, details: '', - metadata: serialised + metadata: serialised, }); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); @@ -360,7 +364,7 @@ describe('GRPC utils', () => { message: '', code: 2, details: '', - metadata: serialised + metadata: serialised, }); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe(''); @@ -397,7 +401,7 @@ describe('GRPC utils', () => { message: '', code: 2, details: '', - metadata: serialised + metadata: serialised, }); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); From b37de4da89079cd43154ff3110ae4be43a9e9187 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Wed, 4 May 2022 16:14:42 +1000 Subject: [PATCH 09/74] syntax: removing index imports --- src/PolykeyAgent.ts | 38 ++++++++++--------- .../service/gestaltsActionsGetByIdentity.ts | 16 +++++--- tests/client/rpcVaults.test.ts | 6 +-- tests/client/utils.ts | 5 +-- tests/grpc/GRPCClient.test.ts | 7 ++-- tests/grpc/GRPCServer.test.ts | 8 ++-- tests/grpc/utils/GRPCClientTest.ts | 5 ++- tests/grpc/utils/testService.ts | 3 +- 8 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/PolykeyAgent.ts b/src/PolykeyAgent.ts index ba9cafc37..a72ba5f16 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; diff --git a/src/client/service/gestaltsActionsGetByIdentity.ts b/src/client/service/gestaltsActionsGetByIdentity.ts index 3ec511381..db6faa41e 100644 --- a/src/client/service/gestaltsActionsGetByIdentity.ts +++ b/src/client/service/gestaltsActionsGetByIdentity.ts @@ -1,12 +1,14 @@ +import type Logger from '@matrixai/logger'; import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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({ @@ -58,7 +60,9 @@ function gestaltsActionsGetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + if (!(e instanceof validationErrors.ErrorValidation)) { + logger.error(e); + } return; } }; diff --git a/tests/client/rpcVaults.test.ts b/tests/client/rpcVaults.test.ts index 6e477e62d..96f3db089 100644 --- a/tests/client/rpcVaults.test.ts +++ b/tests/client/rpcVaults.test.ts @@ -7,12 +7,12 @@ 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'; diff --git a/tests/client/utils.ts b/tests/client/utils.ts index 247b1da8b..c3cc7d25b 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'; diff --git a/tests/grpc/GRPCClient.test.ts b/tests/grpc/GRPCClient.test.ts index a4f83a1e0..de8618005 100644 --- a/tests/grpc/GRPCClient.test.ts +++ b/tests/grpc/GRPCClient.test.ts @@ -10,9 +10,10 @@ 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'; 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/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 1297c354c..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'; From 41bfb8be49840bf8924fe8391944597ad0bb45ad Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Sat, 7 May 2022 17:41:51 +1000 Subject: [PATCH 10/74] fix: integrating db changes into ACL --- src/acl/ACL.ts | 719 +++++++++++++++++++++++---------------------- src/locks/Locks.ts | 115 -------- src/locks/index.ts | 1 - 3 files changed, 365 insertions(+), 470 deletions(-) delete mode 100644 src/locks/Locks.ts delete mode 100644 src/locks/index.ts diff --git a/src/acl/ACL.ts b/src/acl/ACL.ts index 02b2868ff..6245ebace 100644 --- a/src/acl/ACL.ts +++ b/src/acl/ACL.ts @@ -5,7 +5,6 @@ import type { Permission, VaultActions, } from './types'; -import type { Locks } from '../locks'; import type { NodeId } from '../nodes/types'; import type { GestaltAction } from '../gestalts/types'; import type { VaultAction, VaultId } from '../vaults/types'; @@ -18,6 +17,7 @@ import { 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 aclUtils from './utils'; import * as aclErrors from './errors'; @@ -46,7 +46,7 @@ class ACL { protected logger: Logger; protected db: DB; - protected locks: Locks; + protected locks: LockBox = new LockBox(); protected aclDbPath: LevelPath = [this.constructor.name]; /** @@ -120,6 +120,23 @@ class ACL { this.logger.info(`Destroyed ${this.constructor.name}`); } + @ready(new aclErrors.ErrorACLNotRunning()) + public async withTransactionF( + ...params: [ + ...keyPaths: Array, + f: (tran: DBTransaction) => Promise, + ] + ): Promise { + const f = params.pop() as (tran: DBTransaction) => Promise; + const lockRequests = (params as Array).map< + [KeyPath, typeof Lock] + >((keyPath) => [keyPath, Lock]); + return withF( + [this.db.transaction(), this.locks.lock(...lockRequests)], + ([tran]) => f(tran), + ); + } + @ready(new aclErrors.ErrorACLNotRunning()) public async sameNodePerm( nodeId1: NodeId, @@ -135,15 +152,8 @@ class ACL { nodeId2.toBuffer(), ] as unknown as KeyPath; if (tran == null) { - return withF( - [ - this.db.transaction(), - this.locks.lockRead( - dbUtils.keyPathToKey(nodeId1Path).toString('binary'), - dbUtils.keyPathToKey(nodeId2Path).toString('binary'), - ), - ], - async ([tran]) => this.sameNodePerm(nodeId1, nodeId2, tran), + return this.withTransactionF(nodeId1Path, nodeId2Path, async (tran) => + this.sameNodePerm(nodeId1, nodeId2, tran), ); } const permId1 = await tran.get(nodeId1Path, true); @@ -157,7 +167,7 @@ class ACL { } @ready(new aclErrors.ErrorACLNotRunning()) - public async getNodePerms(): Promise>> { + public async getNodePerms(tran?: DBTransaction): Promise>> { return await this._transaction(async () => { const permIds: Record< PermissionIdString, @@ -198,7 +208,7 @@ class ACL { } @ready(new aclErrors.ErrorACLNotRunning()) - public async getVaultPerms(): Promise< + public async getVaultPerms(tran?: DBTransaction): Promise< Record> > { return await this._transaction(async () => { @@ -261,22 +271,29 @@ 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 { + const nodeIdPath = [ + ...this.aclNodesDbPath, + nodeId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(nodeIdPath, 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(nodeIdPath, true); + if (permId == null) { + return; + } + const permIdPath = [ + ...this.aclPermsDbPath, + permId, + ] as unknown as KeyPath; + const perm = (await tran.get(permIdPath)) as Ref; + return perm.object; } /** @@ -287,127 +304,144 @@ 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(), + const vaultIdPath = [ + ...this.aclVaultsDbPath, + vaultId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(vaultIdPath, async (tran) => + this.getVaultPerm(vaultId, tran), + ); + } + const nodeIds = await tran.get>( + vaultIdPath + ); + if (nodeIds == null) { + return {}; + } + const perms: Record = {}; + const nodeIdsGc: Set = new Set(); + for (const nodeIdString in nodeIds) { + const nodeId: NodeId = IdInternal.fromString(nodeIdString); + const nodeIdPath = [ + ...this.aclNodesDbPath, + nodeId.toBuffer(), + ] as unknown as KeyPath; + const permId = await tran.get( + nodeIdPath, + true, ); - if (nodeIds == null) { - return {}; + 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 permIdPath = [ + ...this.aclPermsDbPath, + permId, + ] as unknown as KeyPath; + const permRef = (await tran.get( + permIdPath, + )) 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(vaultIdPath, nodeIds); + } + 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, + const nodeIdPath = [ + ...this.aclNodesDbPath, + nodeId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(nodeIdPath, 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( + nodeIdPath, + 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: {}, + }, + }; + const permIdPath = [ + ...this.aclPermsDbPath, + permId.toBuffer(), + ] as unknown as KeyPath; + await tran.put(permIdPath, permRef); + await tran.put(nodeIdPath, permId.toBuffer()); + } else { + const permIdPath = [ + ...this.aclPermsDbPath, + permId, + ] as unknown as KeyPath; + const permRef = (await tran.get( + permIdPath + )) as Ref; + permRef.object.gestalt[action] = null; + await tran.put(permIdPath, permRef); + } } @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, + const nodeIdPath = [ + ...this.aclNodesDbPath, + nodeId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(nodeIdPath, 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( + nodeIdPath, + true, + ); + if (permId == null) { + return; + } + const permIdPath = [ + ...this.aclPermsDbPath, + permId, + ] as unknown as KeyPath; + const permRef = (await tran.get( + permIdPath + )) as Ref; + delete permRef.object.gestalt[action]; + await tran.put(permIdPath, permRef); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -415,55 +449,49 @@ 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, + const vaultIdPath = [ + ...this.aclVaultsDbPath, + vaultId.toBuffer(), + ] as unknown as KeyPath; + const nodeIdPath = [ + ...this.aclNodesDbPath, + nodeId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(vaultIdPath, nodeIdPath, 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>( + vaultIdPath + )) ?? {}; + const permId = await tran.get( + nodeIdPath, + true, + ); + if (permId == null) { + throw new aclErrors.ErrorACLNodeIdMissing(); + } + nodeIds[nodeId] = null; + const permIdPath = [ + ...this.aclPermsDbPath, + permId, + ] as unknown as KeyPath; + const permRef = (await this.db.get( + permIdPath, + )) 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(permIdPath, permRef); + await tran.put(nodeIdPath, permId); + await tran.put(vaultIdPath, nodeIds); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -471,34 +499,47 @@ 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, + const vaultIdPath = [ + ...this.aclVaultsDbPath, + vaultId.toBuffer(), + ] as unknown as KeyPath; + const nodeIdPath = [ + ...this.aclNodesDbPath, + nodeId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(vaultIdPath, nodeIdPath, 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>( + vaultIdPath + ); + if (nodeIds == null || !(nodeId in nodeIds)) { + return; + } + const permId = await tran.get( + nodeIdPath, + true, + ); + if (permId == null) { + return; + } + const permIdPath = [ + ...this.aclPermsDbPath, + permId, + ] as unknown as KeyPath; + const permRef = (await tran.get( + permIdPath + )) as Ref; + const actions: VaultActions | undefined = permRef.object.vaults[vaultId]; + if (actions == null) { + return; + } + delete actions[action]; + await tran.put(permIdPath, permRef); } /** @@ -510,24 +551,21 @@ 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 = []; + const nodeIdPaths = nodeIds.map((nodeId) => [ + ...this.aclNodesDbPath, + nodeId.toBuffer(), + ] as unknown as KeyPath); + if (tran == null) { + return this.withTransactionF(...nodeIdPaths, 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(), + for (const nodeIdPath of nodeIdPaths) { + const permIdBuffer = await tran.get( + nodeIdPath, true, ); if (permIdBuffer == null) { @@ -538,196 +576,165 @@ class ACL { } for (const permIdString in permIdCounts) { const permId = IdInternal.fromString(permIdString); - const permRef = (await this.db.get( - this.aclPermsDbDomain, + const permIdPath = [ + ...this.aclPermsDbPath, permId.toBuffer(), + ] as unknown as KeyPath; + const permRef = (await tran.get( + permIdPath, )) 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(permIdPath); } else { - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId.toBuffer(), - value: permRef, - }); + await tran.put(permIdPath, permRef); } } - 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, - }); - for (const nodeId of nodeIds) { - ops.push({ - domain: this.aclNodesDbDomain, - type: 'put', - key: nodeId.toBuffer(), - value: permId.toBuffer(), - raw: true, - }); + const permIdPath = [ + ...this.aclPermsDbPath, + permId.toBuffer(), + ] as unknown as KeyPath; + await tran.put(permIdPath, permRef); + for (const nodeIdPath of nodeIdPaths) { + await tran.put(nodeIdPath, permId.toBuffer()); } - 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); - }); } @ready(new aclErrors.ErrorACLNotRunning()) - public async setNodePermOps( + public async setNodePerm( nodeId: NodeId, perm: Permission, - ): Promise> { - const permId = await this.db.get( - this.aclNodesDbDomain, + tran?: DBTransaction, + ): Promise { + const nodeIdPath = [ + ...this.aclNodesDbPath, nodeId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(nodeIdPath, async (tran) => + this.setNodePerm(nodeId, perm, tran), + ); + } + const permId = await tran.get( + nodeIdPath, 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, - }, - ); + const permIdPath = [ + ...this.aclPermsDbPath, + permId.toBuffer(), + ] as unknown as KeyPath; + await tran.put(permIdPath, permRef); + await tran.put(nodeIdPath, permId.toBuffer()); } else { // The entire gestalt's perm gets replaced, therefore the count stays the same - const permRef = (await this.db.get( - this.aclPermsDbDomain, + const permIdPath = [ + ...this.aclPermsDbPath, permId, + ] as unknown as KeyPath; + const permRef = (await tran.get( + permIdPath, )) as Ref; permRef.object = perm; - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: permRef, - }); + await tran.put(permIdPath, 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); - }); - } - - @ready(new aclErrors.ErrorACLNotRunning()) - public async unsetNodePermOps(nodeId: NodeId): Promise> { - const permId = await this.db.get( - this.aclNodesDbDomain, + public async unsetNodePerm( + nodeId: NodeId, + tran?: DBTransaction, + ): Promise { + const nodeIdPath = [ + ...this.aclNodesDbPath, nodeId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(nodeIdPath, async (tran) => + this.unsetNodePerm(nodeId, tran), + ); + } + const permId = await tran.get( + nodeIdPath, true, ); if (permId == null) { - return []; + return; } - const ops: Array = []; - const permRef = (await this.db.get( - this.aclPermsDbDomain, + const permIdPath = [ + ...this.aclNodesDbPath, permId, + ] as unknown as KeyPath; + const permRef = (await tran.get( + permIdPath, )) as Ref; const count = --permRef.count; if (count === 0) { - ops.push({ - type: 'del', - domain: this.aclPermsDbDomain, - key: permId, - }); + await tran.del(permIdPath); } else { - ops.push({ - type: 'put', - domain: this.aclPermsDbDomain, - key: permId, - value: permRef, - }); + await tran.put(permIdPath, permRef); } - ops.push({ - type: 'del', - domain: this.aclNodesDbDomain, - key: nodeId.toBuffer(), - }); + await tran.del(nodeIdPath); // 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 { + const vaultIdPath = [ + ...this.aclVaultsDbPath, + vaultId.toBuffer(), + ] as unknown as KeyPath; + if (tran == null) { + return this.withTransactionF(vaultIdPath, 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>( + vaultIdPath, + ); + if (nodeIds == null) { + return; + } + for (const nodeIdString in nodeIds) { + const nodeId: NodeId = IdInternal.fromString(nodeIdString); + const nodeIdPath = [ + ...this.aclNodesDbPath, + nodeId.toBuffer(), + ] as unknown as KeyPath; + const permId = await tran.get( + nodeIdPath, + 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 permIdPath = [ + ...this.aclPermsDbPath, + permId, + ] as unknown as KeyPath; + const perm = (await tran.get( + permIdPath, + )) as Ref; + delete perm.object.vaults[vaultId]; + await tran.put(permIdPath, perm); + } + await tran.del(vaultIdPath); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -735,6 +742,7 @@ class ACL { nodeId: NodeId, nodeIdsJoin: Array, perm?: Permission, + tran?: DBTransaction, ): Promise { await this._transaction(async () => { const ops = await this.joinNodePermOps(nodeId, nodeIdsJoin, perm); @@ -747,6 +755,7 @@ class ACL { nodeId: NodeId, nodeIdsJoin: Array, perm?: Permission, + tran?: DBTransaction, ): Promise> { const permId = await this.db.get( this.aclNodesDbDomain, @@ -817,6 +826,7 @@ class ACL { public async joinVaultPerms( vaultId: VaultId, vaultIdsJoin: Array, + tran?: DBTransaction, ): Promise { await this._transaction(async () => { const ops = await this.joinVaultPermsOps(vaultId, vaultIdsJoin); @@ -828,6 +838,7 @@ class ACL { private async joinVaultPermsOps( vaultId: VaultId, vaultIdsJoin: Array, + tran: DBTransaction, ): Promise> { const nodeIds = await this.db.get>( this.aclVaultsDbDomain, diff --git a/src/locks/Locks.ts b/src/locks/Locks.ts deleted file mode 100644 index 2434d30dd..000000000 --- a/src/locks/Locks.ts +++ /dev/null @@ -1,115 +0,0 @@ -import type { ResourceAcquire, ResourceRelease } from '@matrixai/resources'; -import type { NonEmptyArray } from '../types'; -import { RWLockWriter } from '@matrixai/async-locks'; - -/** - * Generic dynamic read-write lock collection - * This enables advisory-locking across all domains - */ -class Locks { - protected _locks: Map; - - get locks(): ReadonlyMap { - return this._locks; - } - - /** - * Read-lock a sequence of ids - * The ids will be sorted before locking to ensure lock-hierarchy - * in order to prevent deadlocks - */ - public lockRead( - ...ids: NonEmptyArray - ): ResourceAcquire> { - return async () => { - ids.sort(); - const locks: Array<[string, ResourceRelease, RWLockWriter]> = []; - for (const id of ids) { - let lock = this._locks.get(id); - if (lock == null) { - lock = new RWLockWriter(); - this._locks.set(id, lock); - } - let lockRelease: ResourceRelease; - try { - [lockRelease] = await lock.acquireRead(); - } catch (e) { - // Release all intermediate locks in reverse order - locks.reverse(); - for (const [id, lockRelease, lock] of locks) { - await lockRelease(); - if (!lock!.isLocked()) { - this._locks.delete(id); - } - } - throw e; - } - locks.push([id, lockRelease, lock]); - } - return [ - async () => { - // Release all locks in reverse order - locks.reverse(); - for (const [id, lockRelease, lock] of locks) { - await lockRelease(); - if (!lock!.isLocked()) { - this._locks.delete(id); - } - } - }, - locks.map(([, , lock]) => lock) as NonEmptyArray, - ]; - }; - } - - /** - * Write-lock a sequence of ids - * The ids will be sorted before locking to ensure lock-hierarchy - * in order to prevent deadlocks - */ - public lockWrite( - ...ids: NonEmptyArray - ): ResourceAcquire> { - return async () => { - ids.sort(); - const locks: Array<[string, ResourceRelease, RWLockWriter]> = []; - for (const id of ids) { - let lock = this._locks.get(id); - if (lock == null) { - lock = new RWLockWriter(); - this._locks.set(id, lock); - } - let lockRelease: ResourceRelease; - try { - [lockRelease] = await lock.acquireWrite(); - } catch (e) { - // Release all intermediate locks in reverse order - locks.reverse(); - for (const [id, lockRelease, lock] of locks) { - await lockRelease(); - if (!lock!.isLocked()) { - this._locks.delete(id); - } - } - throw e; - } - locks.push([id, lockRelease, lock]); - } - return [ - async () => { - // Release all locks in reverse order - locks.reverse(); - for (const [id, lockRelease, lock] of locks) { - await lockRelease(); - if (!lock!.isLocked()) { - this._locks.delete(id); - } - } - }, - locks.map(([, , lock]) => lock) as NonEmptyArray, - ]; - }; - } -} - -export default Locks; diff --git a/src/locks/index.ts b/src/locks/index.ts deleted file mode 100644 index fe97431ee..000000000 --- a/src/locks/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Locks } from './Locks'; From 0c55d3e262cc6b8c533b71e3e4c6b11f9f084194 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 9 May 2022 16:51:38 +1000 Subject: [PATCH 11/74] fix: changing `es6` to `es2021` in `./eslintrc` --- .eslintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index d53f180f4..c8db5d863 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,7 +2,7 @@ "env": { "browser": true, "commonjs": true, - "es6": true, + "es2021": true, "node": true, "jest": true }, From e54bfcd32614031e62a2632c403b476fb3158455 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 9 May 2022 16:52:06 +1000 Subject: [PATCH 12/74] fix: integrating db changes into ACL --- src/acl/ACL.ts | 642 +++++------ src/discovery/Discovery.ts | 12 +- src/gestalts/GestaltGraph.ts | 1186 +++++++++------------ src/identities/IdentitiesManager.ts | 179 ++-- src/nodes/NodeConnectionManager.ts | 8 +- src/nodes/NodeGraph.ts | 392 +++---- src/nodes/NodeManager.ts | 2 +- src/notifications/NotificationsManager.ts | 90 +- src/sigchain/Sigchain.ts | 2 +- tests/acl/ACL.test.ts | 73 +- tests/gestalts/GestaltGraph.test.ts | 4 +- tests/utils.ts | 210 ++-- 12 files changed, 1226 insertions(+), 1574 deletions(-) diff --git a/src/acl/ACL.ts b/src/acl/ACL.ts index 6245ebace..e97dc6c30 100644 --- a/src/acl/ACL.ts +++ b/src/acl/ACL.ts @@ -1,4 +1,4 @@ -import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; +import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; import type { PermissionId, PermissionIdString, @@ -17,7 +17,6 @@ import { 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 aclUtils from './utils'; import * as aclErrors from './errors'; @@ -46,7 +45,6 @@ class ACL { protected logger: Logger; protected db: DB; - protected locks: LockBox = new LockBox(); protected aclDbPath: LevelPath = [this.constructor.name]; /** @@ -64,31 +62,6 @@ class ACL { */ protected aclVaultsDbPath: LevelPath = [this.constructor.name, 'vaults']; - // Lock across the usages of the DB - // it makes sense to use - // Symbol.for("key") - // symbol for is found in teh global registry, if it doesn't exist, it is added to the global registry and returned - // we can identify our locks by this - // to do this, we should have a global lock system in case we want to LOCK across multiple domains - // then other domains can also ensure those locks are being done as well - // and it is a like a PATH for a specific domain - // we can pass a keyPath - // and we can lock a level path - // well right now it can only be a keypath - // this.acquireLock(key: Buffer) - // and we identify our key buffer into a collection - // we can do a collection struce - // the symbols don't quite make sense, since we cannot attach a lock there anyway - // so we have to do this as well - // if it is not the DB problem we can just do this - // this.acquireLock() - - // KeyPath | string | Buffer - // locking an entire level is an interesting idea - // then you could have a very specific locking system - // No more single mutex - // protected lock: Mutex = new Mutex(); - protected generatePermId: () => PermissionId; constructor({ db, logger }: { db: DB; logger: Logger }) { @@ -122,19 +95,9 @@ class ACL { @ready(new aclErrors.ErrorACLNotRunning()) public async withTransactionF( - ...params: [ - ...keyPaths: Array, - f: (tran: DBTransaction) => Promise, - ] + f: (tran: DBTransaction) => Promise, ): Promise { - const f = params.pop() as (tran: DBTransaction) => Promise; - const lockRequests = (params as Array).map< - [KeyPath, typeof Lock] - >((keyPath) => [keyPath, Lock]); - return withF( - [this.db.transaction(), this.locks.lock(...lockRequests)], - ([tran]) => f(tran), - ); + return withF([this.db.transaction()], ([tran]) => f(tran)); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -143,21 +106,19 @@ class ACL { nodeId2: NodeId, tran?: DBTransaction, ): Promise { - const nodeId1Path = [ - ...this.aclNodesDbPath, - nodeId1.toBuffer(), - ] as unknown as KeyPath; - const nodeId2Path = [ - ...this.aclNodesDbPath, - nodeId2.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(nodeId1Path, nodeId2Path, async (tran) => + return this.withTransactionF(async (tran) => this.sameNodePerm(nodeId1, nodeId2, tran), ); } - const permId1 = await tran.get(nodeId1Path, true); - const permId2 = await tran.get(nodeId2Path, 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), @@ -167,103 +128,92 @@ class ACL { } @ready(new aclErrors.ErrorACLNotRunning()) - public async getNodePerms(tran?: DBTransaction): 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(tran?: DBTransaction): 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; } - 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, - }); + 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; } - vaultPerms[vaultId] = nodePerm; + nodePerm[nodeId] = permRef.object; } - await this.db.batch(ops); - return vaultPerms; - }); + if (nodeIdsGc.size > 0) { + // Remove invalid node ids + for (const nodeId of nodeIdsGc) { + delete nodeIds[nodeId]; + } + await tran.put([...this.aclVaultsDbPath, vaultId.toBuffer()], nodeIds); + } + vaultPerms[vaultId] = nodePerm; + } + return vaultPerms; } /** @@ -275,24 +225,22 @@ class ACL { nodeId: NodeId, tran?: DBTransaction, ): Promise { - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(nodeIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.getNodePerm(nodeId, tran), ); } - const permId = await tran.get(nodeIdPath, true); + const permId = await tran.get( + [...this.aclNodesDbPath, nodeId.toBuffer()], + true, + ); if (permId == null) { return; } - const permIdPath = [ - ...this.aclPermsDbPath, - permId, - ] as unknown as KeyPath; - const perm = (await tran.get(permIdPath)) as Ref; + const perm = (await tran.get( + [...this.aclPermsDbPath, permId], + false, + )) as Ref; return perm.object; } @@ -306,17 +254,14 @@ class ACL { vaultId: VaultId, tran?: DBTransaction, ): Promise> { - const vaultIdPath = [ - ...this.aclVaultsDbPath, - vaultId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(vaultIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.getVaultPerm(vaultId, tran), ); } const nodeIds = await tran.get>( - vaultIdPath + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, ); if (nodeIds == null) { return {}; @@ -325,12 +270,8 @@ class ACL { const nodeIdsGc: Set = new Set(); for (const nodeIdString in nodeIds) { const nodeId: NodeId = IdInternal.fromString(nodeIdString); - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; const permId = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { @@ -338,12 +279,9 @@ class ACL { nodeIdsGc.add(nodeId); continue; } - const permIdPath = [ - ...this.aclPermsDbPath, - permId, - ] as unknown as KeyPath; const permRef = (await tran.get( - permIdPath, + [...this.aclPermsDbPath, permId], + false, )) as Ref; if (!(vaultId in permRef.object.vaults)) { // Vault id is missing from the perm @@ -357,7 +295,11 @@ class ACL { for (const nodeId of nodeIdsGc) { delete nodeIds[nodeId]; } - await tran.put(vaultIdPath, nodeIds); + await tran.put( + [...this.aclVaultsDbPath, vaultId.toBuffer()], + nodeIds, + false, + ); } return perms; } @@ -368,17 +310,13 @@ class ACL { action: GestaltAction, tran?: DBTransaction, ): Promise { - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(nodeIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.setNodeAction(nodeId, action, tran), ); } const permId = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { @@ -392,22 +330,23 @@ class ACL { vaults: {}, }, }; - const permIdPath = [ - ...this.aclPermsDbPath, + await tran.put( + [...this.aclPermsDbPath, permId.toBuffer()], + permRef, + false, + ); + await tran.put( + [...this.aclNodesDbPath, nodeId.toBuffer()], permId.toBuffer(), - ] as unknown as KeyPath; - await tran.put(permIdPath, permRef); - await tran.put(nodeIdPath, permId.toBuffer()); + true, + ); } else { - const permIdPath = [ - ...this.aclPermsDbPath, - permId, - ] as unknown as KeyPath; const permRef = (await tran.get( - permIdPath + [...this.aclPermsDbPath, permId], + false, )) as Ref; permRef.object.gestalt[action] = null; - await tran.put(permIdPath, permRef); + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } } @@ -417,31 +356,24 @@ class ACL { action: GestaltAction, tran?: DBTransaction, ): Promise { - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(nodeIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.unsetNodeAction(nodeId, action, tran), ); } const permId = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { return; } - const permIdPath = [ - ...this.aclPermsDbPath, - permId, - ] as unknown as KeyPath; const permRef = (await tran.get( - permIdPath + [...this.aclPermsDbPath, permId], + false, )) as Ref; delete permRef.object.gestalt[action]; - await tran.put(permIdPath, permRef); + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -451,37 +383,27 @@ class ACL { action: VaultAction, tran?: DBTransaction, ): Promise { - const vaultIdPath = [ - ...this.aclVaultsDbPath, - vaultId.toBuffer(), - ] as unknown as KeyPath; - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(vaultIdPath, nodeIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.setVaultAction(vaultId, nodeId, action, tran), ); } const nodeIds = (await tran.get>( - vaultIdPath + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, )) ?? {}; const permId = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { throw new aclErrors.ErrorACLNodeIdMissing(); } nodeIds[nodeId] = null; - const permIdPath = [ - ...this.aclPermsDbPath, - permId, - ] as unknown as KeyPath; - const permRef = (await this.db.get( - permIdPath, + const permRef = (await tran.get( + [...this.aclPermsDbPath, permId], + false, )) as Ref; let actions: VaultActions | undefined = permRef.object.vaults[vaultId]; if (actions == null) { @@ -489,9 +411,13 @@ class ACL { permRef.object.vaults[vaultId] = actions; } actions[action] = null; - await tran.put(permIdPath, permRef); - await tran.put(nodeIdPath, permId); - await tran.put(vaultIdPath, nodeIds); + 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()) @@ -501,45 +427,35 @@ class ACL { action: VaultAction, tran?: DBTransaction, ): Promise { - const vaultIdPath = [ - ...this.aclVaultsDbPath, - vaultId.toBuffer(), - ] as unknown as KeyPath; - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(vaultIdPath, nodeIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.unsetVaultAction(vaultId, nodeId, action, tran), ); } const nodeIds = await tran.get>( - vaultIdPath + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, ); if (nodeIds == null || !(nodeId in nodeIds)) { return; } const permId = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { return; } - const permIdPath = [ - ...this.aclPermsDbPath, - permId, - ] as unknown as KeyPath; const permRef = (await tran.get( - permIdPath + [...this.aclPermsDbPath, permId], + false, )) as Ref; const actions: VaultActions | undefined = permRef.object.vaults[vaultId]; if (actions == null) { return; } delete actions[action]; - await tran.put(permIdPath, permRef); + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } /** @@ -553,19 +469,15 @@ class ACL { perm: Permission, tran?: DBTransaction, ): Promise { - const nodeIdPaths = nodeIds.map((nodeId) => [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath); if (tran == null) { - return this.withTransactionF(...nodeIdPaths, async (tran) => + return this.withTransactionF(async (tran) => this.setNodesPerm(nodeIds, perm, tran), ); } const permIdCounts: Record = {}; - for (const nodeIdPath of nodeIdPaths) { + for (const nodeId of nodeIds) { const permIdBuffer = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permIdBuffer == null) { @@ -576,18 +488,19 @@ class ACL { } for (const permIdString in permIdCounts) { const permId = IdInternal.fromString(permIdString); - const permIdPath = [ - ...this.aclPermsDbPath, - permId.toBuffer(), - ] as unknown as KeyPath; const permRef = (await tran.get( - permIdPath, + [...this.aclPermsDbPath, permId.toBuffer()], + false, )) as Ref; permRef.count = permRef.count - permIdCounts[permId]; if (permRef.count === 0) { - await tran.del(permIdPath); + await tran.del([...this.aclPermsDbPath, permId.toBuffer()]); } else { - await tran.put(permIdPath, permRef); + await tran.put( + [...this.aclPermsDbPath, permId.toBuffer()], + permRef, + false, + ); } } const permId = this.generatePermId(); @@ -595,13 +508,13 @@ class ACL { count: nodeIds.length, object: perm, }; - const permIdPath = [ - ...this.aclPermsDbPath, - permId.toBuffer(), - ] as unknown as KeyPath; - await tran.put(permIdPath, permRef); - for (const nodeIdPath of nodeIdPaths) { - await tran.put(nodeIdPath, permId.toBuffer()); + await tran.put([...this.aclPermsDbPath, permId.toBuffer()], permRef, false); + for (const nodeId of nodeIds) { + await tran.put( + [...this.aclNodesDbPath, nodeId.toBuffer()], + permId.toBuffer(), + true, + ); } } @@ -611,17 +524,13 @@ class ACL { perm: Permission, tran?: DBTransaction, ): Promise { - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(nodeIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.setNodePerm(nodeId, perm, tran), ); } const permId = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { @@ -630,23 +539,24 @@ class ACL { count: 1, object: perm, }; - const permIdPath = [ - ...this.aclPermsDbPath, + await tran.put( + [...this.aclPermsDbPath, permId.toBuffer()], + permRef, + false, + ); + await tran.put( + [...this.aclNodesDbPath, nodeId.toBuffer()], permId.toBuffer(), - ] as unknown as KeyPath; - await tran.put(permIdPath, permRef); - await tran.put(nodeIdPath, permId.toBuffer()); + true, + ); } else { // The entire gestalt's perm gets replaced, therefore the count stays the same - const permIdPath = [ - ...this.aclPermsDbPath, - permId, - ] as unknown as KeyPath; const permRef = (await tran.get( - permIdPath, + [...this.aclPermsDbPath, permId], + false, )) as Ref; permRef.object = perm; - await tran.put(permIdPath, permRef); + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } } @@ -655,36 +565,29 @@ class ACL { nodeId: NodeId, tran?: DBTransaction, ): Promise { - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(nodeIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.unsetNodePerm(nodeId, tran), ); } const permId = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); if (permId == null) { return; } - const permIdPath = [ - ...this.aclNodesDbPath, - permId, - ] as unknown as KeyPath; const permRef = (await tran.get( - permIdPath, + [...this.aclPermsDbPath, permId], + false, )) as Ref; const count = --permRef.count; if (count === 0) { - await tran.del(permIdPath); + await tran.del([...this.aclPermsDbPath, permId]); } else { - await tran.put(permIdPath, permRef); + await tran.put([...this.aclPermsDbPath, permId], permRef, false); } - await tran.del(nodeIdPath); + await tran.del([...this.aclNodesDbPath, nodeId.toBuffer()]); // We do not remove the node id from the vaults // they can be removed later upon inspection } @@ -694,29 +597,22 @@ class ACL { vaultId: VaultId, tran?: DBTransaction, ): Promise { - const vaultIdPath = [ - ...this.aclVaultsDbPath, - vaultId.toBuffer(), - ] as unknown as KeyPath; if (tran == null) { - return this.withTransactionF(vaultIdPath, async (tran) => + return this.withTransactionF(async (tran) => this.unsetVaultPerms(vaultId, tran), ); } const nodeIds = await tran.get>( - vaultIdPath, + [...this.aclVaultsDbPath, vaultId.toBuffer()], + false, ); if (nodeIds == null) { return; } for (const nodeIdString in nodeIds) { const nodeId: NodeId = IdInternal.fromString(nodeIdString); - const nodeIdPath = [ - ...this.aclNodesDbPath, - nodeId.toBuffer(), - ] as unknown as KeyPath; const permId = await tran.get( - nodeIdPath, + [...this.aclNodesDbPath, nodeId.toBuffer()], true, ); // Skip if the nodeId doesn't exist @@ -724,17 +620,14 @@ class ACL { if (permId == null) { continue; } - const permIdPath = [ - ...this.aclPermsDbPath, - permId, - ] as unknown as KeyPath; const perm = (await tran.get( - permIdPath, + [...this.aclPermsDbPath, permId], + false, )) as Ref; delete perm.object.vaults[vaultId]; - await tran.put(permIdPath, perm); + await tran.put([...this.aclPermsDbPath, permId], perm, false); } - await tran.del(vaultIdPath); + await tran.del([...this.aclVaultsDbPath, vaultId.toBuffer()]); } @ready(new aclErrors.ErrorACLNotRunning()) @@ -744,40 +637,29 @@ class ACL { 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, - tran?: DBTransaction, - ): 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) { @@ -785,41 +667,24 @@ 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()) @@ -828,32 +693,23 @@ class ACL { 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, - tran: DBTransaction, - ): 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) { @@ -861,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 @@ -875,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/discovery/Discovery.ts b/src/discovery/Discovery.ts index 900b6b63f..a6d6c1129 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, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { DiscoveryQueueId, DiscoveryQueueIdGenerator } from './types'; import type { NodeId, NodeInfo } from '../nodes/types'; import type NodeManager from '../nodes/NodeManager'; @@ -18,7 +17,6 @@ import type { Sigchain } from '../sigchain'; import type { KeyManager } from '../keys'; 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 { @@ -27,6 +25,9 @@ import { status, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { IdInternal } from '@matrixai/id'; +import { withF } from '@matrixai/resources'; +import { Lock, LockBox } from '@matrixai/async-locks'; +import { utils as dbUtils } from '@matrixai/db'; import * as idUtils from '@matrixai/id/dist/utils'; import * as discoveryUtils from './utils'; import * as discoveryErrors from './errors'; @@ -88,9 +89,8 @@ class Discovery { 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; 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/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/nodes/NodeConnectionManager.ts b/src/nodes/NodeConnectionManager.ts index b7c68dfa9..84e9ddfa9 100644 --- a/src/nodes/NodeConnectionManager.ts +++ b/src/nodes/NodeConnectionManager.ts @@ -132,7 +132,7 @@ 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 = connAndLock.lock.read(); // Resetting TTL timer connAndLock.timer?.refresh(); // Return tuple of [ResourceRelease, Resource] @@ -241,7 +241,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, @@ -267,7 +267,7 @@ class NodeConnectionManager { 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, @@ -360,7 +360,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 diff --git a/src/nodes/NodeGraph.ts b/src/nodes/NodeGraph.ts index 4237b5529..f1f12e149 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,37 +96,18 @@ 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), + ); } /** @@ -144,18 +116,24 @@ class NodeGraph { * @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, + public async getNode(nodeId: NodeId, tran?: DBTransaction): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getNode(nodeId, tran), ); - if (bucket != null && nodeId in bucket) { - return bucket[nodeId].address; - } - return; - }); + } + 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; } /** @@ -174,47 +152,51 @@ class NodeGraph { * @param bucketIndex */ @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 +221,7 @@ class NodeGraph { throw new nodesErrors.ErrorNodeGraphOversizedBucket(); } } - return [ - { - type: 'put', - domain: this.nodeGraphBucketsDbDomain, - key: bucketIndex, - value: bucket, - }, - ]; + await tran.put(bucketPath, bucket); } /** @@ -258,38 +233,30 @@ 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, + ] as unknown as KeyPath; + const bucket = await tran.get( + bucketPath, ); - const ops: Array = []; 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; } /** @@ -297,39 +264,29 @@ class NodeGraph { * @param nodeId */ @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, + ] as unknown as KeyPath; + const bucket = await tran.get( + bucketPath ); - const ops: Array = []; 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 +306,20 @@ 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({ key: false }, [ + ...this.nodeGraphBucketsDbPath, + ])) { + const bucket = dbUtils.deserialize(v); + buckets.push(bucket); + } + return buckets; } /** @@ -372,63 +330,65 @@ 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(); + // 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 = dbUtils.deserialize(k); + 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..8035f0bfa 100644 --- a/src/nodes/NodeManager.ts +++ b/src/nodes/NodeManager.ts @@ -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'; diff --git a/src/notifications/NotificationsManager.ts b/src/notifications/NotificationsManager.ts index 44974ae67..b648a2b81 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 { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { utils as idUtils } from '@matrixai/id'; +import { utils as dbUtils } from '@matrixai/db'; +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; + + /** + * 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,33 +119,26 @@ 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(); + await this.db.clear(this.notificationsDbPath); } - this.notificationsDb = notificationsDb; - this.notificationsMessagesDb = notificationsMessagesDb; - // Getting latest ID and creating ID generator let latestId: NotificationId | undefined; - const keyStream = this.notificationsMessagesDb.createKeyStream({ - limit: 1, - reverse: true, - }); + // for await (const [k] of tran.iterator({ value: false }, [ + // ...this.nodeGraphBucketsDbPath, + // ])) { + // const keyStream = this.notificationsMessagesDb.createKeyStream({ + // limit: 1, + // reverse: true, + // }); + await withF( + [this.db.transaction()], + ([tran]) => async (tran) => tran.iterator({ limit: 1, reverse: true, value: false }, [...this.notificationsMessagesDbPath]) + } for await (const o of keyStream) { latestId = IdInternal.fromBuffer(o as Buffer); } diff --git a/src/sigchain/Sigchain.ts b/src/sigchain/Sigchain.ts index 5d5744bf4..19baf94cf 100644 --- a/src/sigchain/Sigchain.ts +++ b/src/sigchain/Sigchain.ts @@ -8,7 +8,7 @@ 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'; 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/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/utils.ts b/tests/utils.ts index 3f446b465..c32329886 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -1,19 +1,19 @@ -import type { StatusLive } from '@/status/types'; +// Import type { StatusLive } from '@/status/types'; import type { NodeId } from '@/nodes/types'; -import type { Host } from '@/network/types'; +// Import type { Host } from '@/network/types'; import path from 'path'; import fs from 'fs'; import lock from 'fd-lock'; -import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +// Import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; -import PolykeyAgent from '@/PolykeyAgent'; -import Status from '@/status/Status'; -import GRPCClientClient from '@/client/GRPCClientClient'; -import * as clientUtils from '@/client/utils'; +// Import PolykeyAgent from '@/PolykeyAgent'; +// import Status from '@/status/Status'; +// import GRPCClientClient from '@/client/GRPCClientClient'; +// import * as clientUtils from '@/client/utils'; import * as keysUtils from '@/keys/utils'; -import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +// Import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import { sleep } from '@/utils'; -import config from '@/config'; +// Import config from '@/config'; /** * Setup the global keypair @@ -83,105 +83,105 @@ async function setupGlobalKeypair() { * * Ensure client-side side-effects are removed at the end of each test * * Ensure server-side side-effects are removed at the end of each test */ -async function setupGlobalAgent( - logger: Logger = new Logger(setupGlobalAgent.name, LogLevel.WARN, [ - new StreamHandler(), - ]), -) { - const globalAgentPassword = 'password'; - const globalAgentDir = path.join(globalThis.dataDir, 'agent'); - // The references directory will act like our reference count - await fs.promises.mkdir(path.join(globalAgentDir, 'references'), { - recursive: true, - }); - const pid = process.pid.toString(); - // Plus 1 to the reference count - await fs.promises.writeFile(path.join(globalAgentDir, 'references', pid), ''); - const globalAgentLock = await fs.promises.open( - path.join(globalThis.dataDir, 'agent.lock'), - fs.constants.O_WRONLY | fs.constants.O_CREAT, - ); - while (!lock(globalAgentLock.fd)) { - await sleep(1000); - } - const status = new Status({ - statusPath: path.join(globalAgentDir, config.defaults.statusBase), - statusLockPath: path.join(globalAgentDir, config.defaults.statusLockBase), - fs, - }); - let statusInfo = await status.readStatus(); - if (statusInfo == null || statusInfo.status === 'DEAD') { - await PolykeyAgent.createPolykeyAgent({ - password: globalAgentPassword, - nodePath: globalAgentDir, - networkConfig: { - proxyHost: '127.0.0.1' as Host, - forwardHost: '127.0.0.1' as Host, - agentHost: '127.0.0.1' as Host, - clientHost: '127.0.0.1' as Host, - }, - keysConfig: { - rootKeyPairBits: 2048, - }, - seedNodes: {}, // Explicitly no seed nodes on startup - logger, - }); - statusInfo = await status.readStatus(); - } - return { - globalAgentDir, - globalAgentPassword, - globalAgentStatus: statusInfo as StatusLive, - globalAgentClose: async () => { - // Closing the global agent cannot be done in the globalTeardown - // This is due to a sequence of reasons: - // 1. The global agent is not started as a separate process - // 2. Because we need to be able to mock dependencies - // 3. This means it is part of a jest worker process - // 4. Which will block termination of the jest worker process - // 5. Therefore globalTeardown will never get to execute - // 6. The global agent is not part of globalSetup - // 7. Because not all tests need the global agent - // 8. Therefore setupGlobalAgent is lazy and executed by jest worker processes - try { - await fs.promises.rm(path.join(globalAgentDir, 'references', pid)); - // If the references directory is not empty - // there are other processes still using the global agent - try { - await fs.promises.rmdir(path.join(globalAgentDir, 'references')); - } catch (e) { - if (e.code === 'ENOTEMPTY') { - return; - } - throw e; - } - // Stopping may occur in a different jest worker process - // therefore we cannot rely on pkAgent, but instead use GRPC - const statusInfo = (await status.readStatus()) as StatusLive; - const grpcClient = await GRPCClientClient.createGRPCClientClient({ - nodeId: statusInfo.data.nodeId, - host: statusInfo.data.clientHost, - port: statusInfo.data.clientPort, - tlsConfig: { keyPrivatePem: undefined, certChainPem: undefined }, - logger, - }); - const emptyMessage = new utilsPB.EmptyMessage(); - const meta = clientUtils.encodeAuthFromPassword(globalAgentPassword); - // This is asynchronous - await grpcClient.agentStop(emptyMessage, meta); - await grpcClient.destroy(); - await status.waitFor('DEAD'); - } finally { - lock.unlock(globalAgentLock.fd); - await globalAgentLock.close(); - } - }, - }; -} +// async function setupGlobalAgent( +// logger: Logger = new Logger(setupGlobalAgent.name, LogLevel.WARN, [ +// new StreamHandler(), +// ]), +// ) { +// const globalAgentPassword = 'password'; +// const globalAgentDir = path.join(globalThis.dataDir, 'agent'); +// // The references directory will act like our reference count +// await fs.promises.mkdir(path.join(globalAgentDir, 'references'), { +// recursive: true, +// }); +// const pid = process.pid.toString(); +// // Plus 1 to the reference count +// await fs.promises.writeFile(path.join(globalAgentDir, 'references', pid), ''); +// const globalAgentLock = await fs.promises.open( +// path.join(globalThis.dataDir, 'agent.lock'), +// fs.constants.O_WRONLY | fs.constants.O_CREAT, +// ); +// while (!lock(globalAgentLock.fd)) { +// await sleep(1000); +// } +// const status = new Status({ +// statusPath: path.join(globalAgentDir, config.defaults.statusBase), +// statusLockPath: path.join(globalAgentDir, config.defaults.statusLockBase), +// fs, +// }); +// let statusInfo = await status.readStatus(); +// if (statusInfo == null || statusInfo.status === 'DEAD') { +// await PolykeyAgent.createPolykeyAgent({ +// password: globalAgentPassword, +// nodePath: globalAgentDir, +// networkConfig: { +// proxyHost: '127.0.0.1' as Host, +// forwardHost: '127.0.0.1' as Host, +// agentHost: '127.0.0.1' as Host, +// clientHost: '127.0.0.1' as Host, +// }, +// keysConfig: { +// rootKeyPairBits: 2048, +// }, +// seedNodes: {}, // Explicitly no seed nodes on startup +// logger, +// }); +// statusInfo = await status.readStatus(); +// } +// return { +// globalAgentDir, +// globalAgentPassword, +// globalAgentStatus: statusInfo as StatusLive, +// globalAgentClose: async () => { +// // Closing the global agent cannot be done in the globalTeardown +// // This is due to a sequence of reasons: +// // 1. The global agent is not started as a separate process +// // 2. Because we need to be able to mock dependencies +// // 3. This means it is part of a jest worker process +// // 4. Which will block termination of the jest worker process +// // 5. Therefore globalTeardown will never get to execute +// // 6. The global agent is not part of globalSetup +// // 7. Because not all tests need the global agent +// // 8. Therefore setupGlobalAgent is lazy and executed by jest worker processes +// try { +// await fs.promises.rm(path.join(globalAgentDir, 'references', pid)); +// // If the references directory is not empty +// // there are other processes still using the global agent +// try { +// await fs.promises.rmdir(path.join(globalAgentDir, 'references')); +// } catch (e) { +// if (e.code === 'ENOTEMPTY') { +// return; +// } +// throw e; +// } +// // Stopping may occur in a different jest worker process +// // therefore we cannot rely on pkAgent, but instead use GRPC +// const statusInfo = (await status.readStatus()) as StatusLive; +// const grpcClient = await GRPCClientClient.createGRPCClientClient({ +// nodeId: statusInfo.data.nodeId, +// host: statusInfo.data.clientHost, +// port: statusInfo.data.clientPort, +// tlsConfig: { keyPrivatePem: undefined, certChainPem: undefined }, +// logger, +// }); +// const emptyMessage = new utilsPB.EmptyMessage(); +// const meta = clientUtils.encodeAuthFromPassword(globalAgentPassword); +// // This is asynchronous +// await grpcClient.agentStop(emptyMessage, meta); +// await grpcClient.destroy(); +// await status.waitFor('DEAD'); +// } finally { +// lock.unlock(globalAgentLock.fd); +// await globalAgentLock.close(); +// } +// }, +// }; +// } function generateRandomNodeId(): NodeId { const random = keysUtils.getRandomBytesSync(16).toString('hex'); return IdInternal.fromString(random); } -export { setupGlobalKeypair, setupGlobalAgent, generateRandomNodeId }; +export { setupGlobalKeypair, generateRandomNodeId }; From 81df01827351e6b7c969d527f8d6dc596db24a75 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 10 May 2022 18:22:50 +1000 Subject: [PATCH 13/74] fix: integrating db changes into vaults --- package-lock.json | 12648 +-------------------------- src/vaults/VaultInternal.ts | 254 +- src/vaults/VaultManager.ts | 511 +- tests/vaults/VaultInternal.test.ts | 126 +- tests/vaults/VaultManager.test.ts | 100 +- tests/vaults/VaultOps.test.ts | 11 +- 6 files changed, 616 insertions(+), 13034 deletions(-) diff --git a/package-lock.json b/package-lock.json index a00bffbdb..9ebc8bfbb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12591 +1,8 @@ { "name": "@matrixai/polykey", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "@matrixai/polykey", - "version": "1.0.0", - "license": "GPL-3.0", - "dependencies": { - "@grpc/grpc-js": "1.3.7", - "@matrixai/async-init": "^1.7.1", - "@matrixai/async-locks": "^2.2.0", - "@matrixai/db": "^3.2.3", - "@matrixai/errors": "^1.0.1", - "@matrixai/id": "^3.3.2", - "@matrixai/logger": "^2.1.0", - "@matrixai/resources": "^1.0.0", - "@matrixai/workers": "^1.3.1", - "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.4.3", - "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": "^26.0.20", - "@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.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", - "grpc_tools_node_protoc_ts": "^5.1.3", - "jest": "^26.6.3", - "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.2.1", - "ts-jest": "^26.4.4", - "ts-node": "^10.4.0", - "tsconfig-paths": "^3.9.0", - "typedoc": "^0.22.15", - "typescript": "^4.5.2", - "typescript-cached-transpile": "0.0.6" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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, - "dependencies": { - "@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", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.6", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "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.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==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "regexpu-core": "^4.7.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-wrap-function": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "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/@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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", - "@babel/plugin-proposal-optional-chaining": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.15.4", - "@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.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==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@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.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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@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.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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@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.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", - "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@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.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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@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.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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@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.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", - "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@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.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==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@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.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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", - "@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.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==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@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/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.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==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - }, - "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-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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "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-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==", - "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-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, - "dependencies": { - "@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", - "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.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==", - "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-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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "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-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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "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.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==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-simple-access": "^7.15.4", - "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.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", - "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", - "dev": true, - "dependencies": { - "@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-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.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==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "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-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==", - "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-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==", - "dev": true, - "dependencies": { - "regenerator-transform": "^0.14.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "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-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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "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-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==", - "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-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==", - "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-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==", - "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-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==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@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", - "@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.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", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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==", - "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.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime/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/@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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, - "dependencies": { - "@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", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "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/@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/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, - "engines": { - "node": ">=0.1.95" - } - }, - "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": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.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/globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@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/@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==", - "dependencies": { - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@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==", - "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": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dev": true, - "dependencies": { - "@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", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "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", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dev": true, - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dev": true, - "dependencies": { - "@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", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "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", - "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" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "node-notifier": "^8.0.0" - } - }, - "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/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/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==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/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, - "dependencies": { - "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" - } - }, - "node_modules/@jest/reporters/node_modules/node-notifier/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, - "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/reporters/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/@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": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/source-map/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/@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==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "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", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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/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/@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": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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/@matrixai/async-init": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@matrixai/async-init/-/async-init-1.7.1.tgz", - "integrity": "sha512-3ELRuEn6AoC3e0b4QccA+NxZl0LilyjYeu6a3Pf9VUVB89EepnNKsk/Afb9qa+B5LvLQwmgHtg4r9VwRpQpnQA==", - "dependencies": { - "@matrixai/async-locks": "^2.2.0", - "@matrixai/errors": "^1.0.1" - } - }, - "node_modules/@matrixai/async-locks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.2.0.tgz", - "integrity": "sha512-i0a551EUMhD1WKpaAyhBUt83ckbOxPB4MlOH8VDzeDyPMAtLI9egCqf3HWOvhN0rSjoH97EmzmfxyAeAgiQzTw==", - "dependencies": { - "@matrixai/errors": "^1.0.1", - "@matrixai/resources": "^1.0.0", - "async-mutex": "^0.3.2" - } - }, - "node_modules/@matrixai/db": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.3.1.tgz", - "integrity": "sha512-EQulm82sBhw1WRhOzzWMoij1SwpjAQHgyokxleTwFHoAnDPMi4WVy4AIxd2lJMPOhhzEFQxCqQmmMYhZWwYAPg==", - "dependencies": { - "@matrixai/async-init": "^1.7.0", - "@matrixai/errors": "^1.0.1", - "@matrixai/logger": "^2.1.0", - "@matrixai/resources": "^1.0.0", - "@matrixai/workers": "^1.3.0", - "@types/abstract-leveldown": "^7.2.0", - "level": "7.0.1", - "threads": "^1.6.5" - } - }, - "node_modules/@matrixai/errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", - "integrity": "sha512-9NbIm3rPMkZz+Ma5tfKduVCWfvYzdHlO89u9mBap7FzJqXkl4yoENjMZm5Do6PvhtIYtRcm6+eTgWvHd6pkdGg==", - "dependencies": { - "ts-custom-error": "^3.2.0" - } - }, - "node_modules/@matrixai/id": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@matrixai/id/-/id-3.3.2.tgz", - "integrity": "sha512-gpW56P7jZILPc0oxyNQvZBkEBn30JPGpslOHIcDoKnCZR8VGZXEKX485xy1WE4MBiQHXdGeiYF8A2CluqTnu3w==", - "dependencies": { - "multiformats": "^9.4.8", - "uuid": "^8.3.2" - } - }, - "node_modules/@matrixai/logger": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@matrixai/logger/-/logger-2.1.0.tgz", - "integrity": "sha512-UmLuXi2PJ03v0Scfl57217RPnjEZDRLlpfdIjIwCfju+kofnhhCI9P7OZu3/FgW147vbvSzWCrrtpwJiLROUUA==" - }, - "node_modules/@matrixai/resources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@matrixai/resources/-/resources-1.0.0.tgz", - "integrity": "sha512-B1ZkySZwOZTIzhK+YTN4HifOTd1dk1ifDUV8/8WgGho2nUZzIMYms7iDmW/ZHUCkqvWupKY6AYvfwnKBOJJnWg==" - }, - "node_modules/@matrixai/workers": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.3.1.tgz", - "integrity": "sha512-AXI37aZ7gSqS5PpUCG7/yfNcnWNYiQUp4yFBY1Z9lKk0zrkQzND1zPjDuJ2E7t6E1a4rwa8vtysj5TVeMCA8jw==", - "dependencies": { - "@matrixai/async-init": "^1.7.0", - "@matrixai/errors": "^1.0.1", - "@matrixai/logger": "^2.1.0", - "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/@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": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "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.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", - "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.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/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.5", - "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.5.tgz", - "integrity": "sha512-6bgv24B+A2bo9AfzReeg5StdiijKzwwnRflA8RLd1V4Yv995LeTmo0z69/MPbBDFSiZWdZHQygLo/ccXhMEDgw==", - "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.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "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": "26.0.24", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz", - "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==", - "dev": true, - "dependencies": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "node_modules/@types/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.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.29.tgz", - "integrity": "sha512-9dDdonLyPJQJ/kdOlDxAah+bTI+u2ccF3k62FErhquDuggoCX6piWez7j7o6yNE+rP2IRcZVQ6Tw4N0P38+rWA==" - }, - "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/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 - }, - "node_modules/@types/pako": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.2.tgz", - "integrity": "sha512-8UJl2MjkqqS6ncpLZqRZ5LmGiFBkbYxocD4e4jmBqGvfRG1RS23gKsBQbdtV9O9GvRyjFTiRHRByjSlKCLlmZw==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", - "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.11", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.11.tgz", - "integrity": "sha512-0z+/apYJwKFz/RHp6mOMxz/y7xOvWPYPevuCEyAY3gXsjtaac02E26RvxA+I96rfvmVH/dEMGXNvyJfViR1FSQ==", - "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.1", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", - "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/scope-manager": "5.4.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.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", - "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.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.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", - "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.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/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==", - "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.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", - "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.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.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.4.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/@typescript-eslint/visitor-keys/node_modules/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, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "node_modules/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": "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-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-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-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, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/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/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/async-lock": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.0.tgz", - "integrity": "sha512-8A7SkiisnEgME2zEedtDYPxUPzdv3x//E7n5IFktPAtMYSEAV7eNJF0rMwrVyUFj6d/8rgajLantbjcNRQYXIg==" - }, - "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/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, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@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", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", - "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.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.2", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.2.2", - "core-js-compat": "^3.16.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.2.2" - }, - "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": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "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/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/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/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, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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==", - "engines": { - "node": ">=0.6" - } - }, - "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.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", - "dev": true, - "dependencies": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", - "escalade": "^3.1.1", - "node-releases": "^2.0.0", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/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/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, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.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.30001269", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", - "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/canonicalize": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.5.tgz", - "integrity": "sha512-mAjKJPIyP0xqqv6IAkvso07StOmz6cmGtNDg3pXCSzXVZOqka7StIkAhJl/zHOi4M2CgpYfD6aeRWbnrmtvBEA==" - }, - "node_modules/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, - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "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/chalk/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/chalk/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/chalk/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/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.5.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", - "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", - "dependencies": { - "css-select": "^4.1.3", - "css-what": "^5.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0", - "domutils": "^2.7.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": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/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": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", - "dev": true - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/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, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/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/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "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/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 - }, - "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/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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.18.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.18.3.tgz", - "integrity": "sha512-4zP6/y0a2RTHN5bRGT7PTq9lVt3WzvffTNjqnTKsXhkAYNDTkdCLOIfAdOLcQ/7TDdyRj3c+NeHe1NmF1eDScw==", - "dev": true, - "dependencies": { - "browserslist": "^4.17.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.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "dependencies": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - }, - "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.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", - "dependencies": { - "node-fetch": "2.6.1" - } - }, - "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.1.3", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", - "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^5.0.0", - "domhandler": "^4.2.0", - "domutils": "^2.6.0", - "nth-check": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/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==", - "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.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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, - "engines": { - "node": ">=0.10" - } - }, - "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==", - "dependencies": { - "mimic-response": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/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, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defined": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz", - "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=" - }, - "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": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "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.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "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.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "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.2.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", - "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", - "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.3.871", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", - "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/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.4.3", - "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.4.3.tgz", - "integrity": "sha512-OQqsGw3eNrMdFpiYRX17nMq1NKKebaA0KXyM9IRY9aPOxpaeOwcdvWnOcvvO9wCxZFNxgy/A2SOZdxnhCe3paA==", - "dependencies": { - "@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", - "errno": "^0.1.7", - "lexicographic-integer": "^1.1.0", - "node-forge": "^0.10.0", - "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" - } - }, - "node_modules/encryptedfs/node_modules/@matrixai/db": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-1.2.1.tgz", - "integrity": "sha512-1W8TORmRX3q3NugZFn0FTgI0mo/n0nWBTXHKXwwPfxtdyNfi18JCj3HVCwWdToOo87ypnS/mqLDIUTSHbF7F3Q==", - "dependencies": { - "@matrixai/async-init": "^1.6.0", - "@matrixai/logger": "^2.1.0", - "@matrixai/workers": "^1.2.5", - "abstract-leveldown": "^7.2.0", - "async-mutex": "^0.3.1", - "level": "7.0.1", - "levelup": "^5.1.1", - "sublevel-prefixer": "^1.0.0", - "subleveldown": "^6.0.1", - "threads": "^1.6.5", - "ts-custom-error": "^3.2.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/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, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/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.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-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.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "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/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, - "engines": { - "node": ">=0.10.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": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "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", - "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", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/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, - "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.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.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-module-utils/node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/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==", - "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.1", - "has": "^1.0.3", - "is-core-module": "^2.8.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-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==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.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-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/node_modules/@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, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "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/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/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-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "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/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/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/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/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/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": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "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.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "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.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "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/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 - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/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/execa/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/execa/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/execa/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/execa/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/execa/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/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/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==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/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, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/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, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/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, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.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.10.10", - "resolved": "https://registry.npmjs.org/fast-fuzzy/-/fast-fuzzy-1.10.10.tgz", - "integrity": "sha512-TkXYYQcLyZ5tbDpg3kj5gq7PNl6vQQQEW99/sBpmYYRPcuCaZElm3FpoOOqwL51+1prhjrzsnGAjWgNCG7iVOA==", - "dependencies": { - "graphemesplit": "^2.4.1" - } - }, - "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "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" - } - }, - "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.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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-extra/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/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/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/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/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/gauge/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/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==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "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": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/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/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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": "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/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.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/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==" - }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "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/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 - }, - "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/handlebars/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/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.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "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-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "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/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/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, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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 - }, - "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.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "engines": { - "node": ">=8.12.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.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "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.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "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.3.3", - "resolved": "https://registry.npmjs.org/ip-num/-/ip-num-1.3.3.tgz", - "integrity": "sha512-1QsiMKglDaemuIktincG1ntr3DvVTV/pU++eyG7vIm4xd+gvtJ9eoB34RRbI9YTqn1U5og16n7+1RgwLhv4RmA==", - "dependencies": { - "big-integer": "^1.6.48" - } - }, - "node_modules/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, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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-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, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "optional": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-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==", - "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.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "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-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, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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.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==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "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.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dependencies": { - "call-bind": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "optional": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/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==", - "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": "^3.0.2" - }, - "bin": { - "isogit": "cli.cjs" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.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-lib-source-maps/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/istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", - "dev": true, - "dependencies": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-changed-files/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/jest-changed-files/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-changed-files/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/jest-changed-files/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/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.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" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dev": true, - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^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", - "walker": "^1.0.7" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@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", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "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" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", - "dev": true, - "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "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==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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.0", - "resolved": "https://registry.npmjs.org/jest-mock-props/-/jest-mock-props-1.9.0.tgz", - "integrity": "sha512-8IlIiZRvovnRuvqcvWZyDv4CyhrUGTbEW/1eKurHr2JY4VhIWQIPlbpt9lqL2nxdGnco+OcgpPBwGYCEeDb2+A==", - "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": "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==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@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", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "dependencies": { - "@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", - "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "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", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "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-runtime/node_modules/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, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/jest-runtime/node_modules/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, - "dependencies": { - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/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, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", - "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.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", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/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": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", - "dev": true, - "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "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/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": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.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": "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/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/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/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/jest/node_modules/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, - "dependencies": { - "@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" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/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/jest/node_modules/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, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/jest/node_modules/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, - "dependencies": { - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest/node_modules/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, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jose": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.3.6.tgz", - "integrity": "sha512-A/JgZGUerqG2IMuxkUDBtZ4aTxg/l1Y+pt/QAAYiRAR3EFlxIE0Su0xdpB8tQcPZK5eudB7g1PHCZ5uHatbY+g==", - "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/jsdom/node_modules/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, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "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.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/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/jsonfile/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/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, - "engines": { - "node": ">=0.10.0" - } - }, - "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-option-wrap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/level-option-wrap/-/level-option-wrap-1.1.0.tgz", - "integrity": "sha1-rSDmjZ88IsiJdTHMaqevWWse0Sk=", - "dependencies": { - "defined": "~0.0.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.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "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.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 - }, - "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.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/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 - }, - "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.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, - "dependencies": { - "tmpl": "1.0.x" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/marked": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", - "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==", - "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.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dev": true, - "dependencies": { - "mime-db": "1.50.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": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "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/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, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "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/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.4.9", - "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.4.9.tgz", - "integrity": "sha512-zA84TTJcRfRMpjvYqy63piBbSEdqlIGqNNSpP6kspqtougqjo60PRhIFo+oAxrjkof14WMCImvr7acK6rPpXLw==" - }, - "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/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/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.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.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-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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-notifier": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.1.tgz", - "integrity": "sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.5", - "shellwords": "^0.1.1", - "uuid": "^8.3.2", - "which": "^2.0.2" - } - }, - "node_modules/node-notifier/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/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 - }, - "node_modules/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, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/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/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": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path/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/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-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/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, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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-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, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "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/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "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.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, - "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/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/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/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "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-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "node_modules/pkg-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=", - "dev": true - }, - "node_modules/pkg-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=", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "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/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/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, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "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": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", - "bin": { - "printj": "bin/printj.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "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/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/reachdown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reachdown/-/reachdown-1.1.0.tgz", - "integrity": "sha512-6LsdRe4cZyOjw4NnvbhUd/rGG7WQ9HMopPr+kyL018Uci4kijtxcGR5kVb5Ln13k4PEE+fEFQbjfOvNw7cnXmA==", - "engines": { - "node": ">=6" - } - }, - "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/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, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/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, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/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, - "engines": { - "node": ">=8" - } - }, - "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": "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==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "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/regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "node_modules/regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", - "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/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 - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/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/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 - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "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-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "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/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, - "engines": { - "node": ">=0.12" - } - }, - "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/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true, - "engines": { - "node": "6.* || >= 7.*" - } - }, - "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/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", - "dev": true, - "dependencies": { - "@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" - }, - "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/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, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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 - }, - "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.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "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": "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==", - "dependencies": { - "decompress-response": "^4.2.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/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, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/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, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/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, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/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, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/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/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/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-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/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 - }, - "node_modules/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, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/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 - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.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/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, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/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, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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/sublevel-prefixer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sublevel-prefixer/-/sublevel-prefixer-1.0.0.tgz", - "integrity": "sha1-TuRZ72Y6yFvyj8ZJ17eWX9ppEHM=" - }, - "node_modules/subleveldown": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/subleveldown/-/subleveldown-6.0.1.tgz", - "integrity": "sha512-Cnf+cn2wISXU2xflY1SFIqfX4hG2d6lFk2P5F8RDQLmiqN9Ir4ExNfUFH6xnmizMseM/t+nMsDUKjN9Kw6ShFA==", - "dependencies": { - "abstract-leveldown": "^7.2.0", - "encoding-down": "^7.1.0", - "inherits": "^2.0.3", - "level-option-wrap": "^1.1.0", - "levelup": "^5.1.1", - "reachdown": "^1.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "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/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/table": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", - "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "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/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": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "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-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, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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": "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==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", - "json5": "2.x", - "lodash": "4.x", - "make-error": "1.x", - "mkdirp": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": ">= 10" - }, - "peerDependencies": { - "jest": ">=26 <27", - "typescript": ">=3.8 <5.0" - } - }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", - "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", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/acorn": { - "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, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "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.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "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.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/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.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/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, - "dependencies": { - "@types/node": "^12.12.7", - "fs-extra": "^8.1.0", - "tslib": "^1.10.0" - }, - "peerDependencies": { - "typescript": "*" - } - }, - "node_modules/typescript-cached-transpile/node_modules/@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 - }, - "node_modules/typescript-cached-transpile/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/typescript-cached-transpile/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/typescript-cached-transpile/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/uglify-js": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", - "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/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/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, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/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/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, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.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-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==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.10.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/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, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "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.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "dependencies": { - "makeerror": "1.0.x" - } - }, - "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/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 - }, - "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==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "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.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "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==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/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": { "@babel/code-frame": { "version": "7.15.8", @@ -14684,8 +2101,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "7.2.0", @@ -16297,8 +3713,7 @@ "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, - "requires": {} + "dev": true }, "eslint-import-resolver-node": { "version": "0.3.6", @@ -18440,22 +5855,19 @@ "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, - "requires": {} + "dev": true }, "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, - "requires": {} + "dev": true }, "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "26.0.0", @@ -19584,35 +6996,6 @@ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true }, - "node-notifier": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.1.tgz", - "integrity": "sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.5", - "shellwords": "^0.1.1", - "uuid": "^8.3.2", - "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, - "peer": 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", @@ -21149,14 +8532,6 @@ } } }, - "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", @@ -21196,6 +8571,14 @@ "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" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -22086,8 +9469,7 @@ "version": "7.5.5", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true, - "requires": {} + "dev": true }, "xml": { "version": "1.0.1", diff --git a/src/vaults/VaultInternal.ts b/src/vaults/VaultInternal.ts index 34597b034..ae2adf6cf 100644 --- a/src/vaults/VaultInternal.ts +++ b/src/vaults/VaultInternal.ts @@ -1,7 +1,6 @@ import type { ReadCommitResult } from 'isomorphic-git'; import type { EncryptedFS } from 'encryptedfs'; -import type { DB, DBDomain, DBLevel } from '@matrixai/db'; -import type { ResourceAcquire } from '@matrixai/resources'; +import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; import type { CommitId, CommitLog, @@ -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: RWLockWriter = new RWLockWriter(); - public readLock: ResourceAcquire = async () => { - const release = await this.lock.acquireRead(); - return [async () => release()]; - }; - - 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, @@ -386,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); }); } @@ -396,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); }); } @@ -404,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 { @@ -433,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, ); }); @@ -444,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 @@ -472,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; }); } @@ -482,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) { @@ -530,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 }, @@ -563,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, ); } @@ -581,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 @@ -593,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, ); } @@ -625,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({ @@ -673,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 @@ -685,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 571b8879d..beb8a525a 100644 --- a/src/vaults/VaultManager.ts +++ b/src/vaults/VaultManager.ts @@ -1,5 +1,5 @@ -import type { DB, DBDomain, DBLevel } from '@matrixai/db'; -import type { ResourceAcquire } from '@matrixai/resources'; +import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; +import type { ResourceAcquire, ResourceRelease } from '@matrixai/resources'; import type { VaultId, VaultName, @@ -58,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(), @@ -120,10 +124,8 @@ 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 vaultsDbPath: LevelPath = [this.constructor.name]; + protected vaultsNamesDbPath: LevelPath = [this.constructor.name, 'names']; protected vaultsNamesLock: RWLockWriter = new RWLockWriter(); // VaultId -> VaultMetadata protected vaultMap: VaultMap = new Map(); @@ -171,53 +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(e.message, { cause: e }); + 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, { - data: { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, - }, - cause: e, - }); + 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 { @@ -225,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 () => { @@ -242,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, @@ -263,7 +258,8 @@ class VaultManager { this.efs.unsetWorkerManager(); } - protected getLock(vaultId: VaultId): RWLockWriter { + 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; @@ -272,20 +268,14 @@ class VaultManager { 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(); } /** @@ -296,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 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, - 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; }); } @@ -345,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, @@ -377,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)}`); @@ -402,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); }); @@ -419,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; @@ -437,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, ); @@ -473,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; @@ -489,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) { @@ -516,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), @@ -540,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); } /** @@ -556,7 +631,14 @@ 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 RWLockWriter(); const vaultIdString = vaultId.toString() as VaultIdString; @@ -571,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) { @@ -598,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( @@ -625,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, }); }); } @@ -646,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( @@ -679,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 @@ -746,14 +855,24 @@ 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) { + const fml = (tran) => this.handleScanVaults(nodeId, tran); + return yield* this.db.withTransactionG(async function* (tran) { + return yield* fml(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}`, @@ -774,7 +893,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, @@ -802,7 +921,16 @@ 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: RWLockWriter; const vaultIdString = vaultId.toString() as VaultIdString; @@ -814,15 +942,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`, ); @@ -833,25 +961,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 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`, ); @@ -861,15 +989,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(); } } } @@ -880,12 +1008,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 @@ -894,7 +1030,7 @@ class VaultManager { const vaults = await Promise.all( vaultIds.map(async (vaultId) => { - return await this.getVault(vaultId); + return await this.getVault(vaultId, tran); }), ); @@ -909,9 +1045,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(); @@ -921,7 +1060,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; } 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..61796e807 100644 --- a/tests/vaults/VaultManager.test.ts +++ b/tests/vaults/VaultManager.test.ts @@ -139,44 +139,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, @@ -1302,7 +1308,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 +1335,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({ @@ -1586,7 +1592,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 +1602,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 +1631,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 +1641,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 +1669,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 +1679,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 +1719,7 @@ describe('VaultManager', () => { db, logger: logger.getChild(VaultManager.name), }); + try { await expect( Promise.all([ @@ -1834,8 +1841,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; From bf29a28b412fd4e38e353127f5aaa2163b85baa6 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 11 May 2022 13:05:36 +1000 Subject: [PATCH 14/74] fix: integrating db changes into Notifications Note that the `transaction` and `_transaction` methods still need te removed. --- src/notifications/NotificationsManager.ts | 397 +++++++++++----------- 1 file changed, 190 insertions(+), 207 deletions(-) diff --git a/src/notifications/NotificationsManager.ts b/src/notifications/NotificationsManager.ts index b648a2b81..83eca6f7b 100644 --- a/src/notifications/NotificationsManager.ts +++ b/src/notifications/NotificationsManager.ts @@ -1,4 +1,4 @@ -import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; +import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; import type { NotificationId, Notification, @@ -12,13 +12,13 @@ import type NodeConnectionManager from '../nodes/NodeConnectionManager'; import type { NodeId } from '../nodes/types'; import Logger from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; +import { Lock } from '@matrixai/async-locks'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { utils as idUtils } from '@matrixai/id'; -import { utils as dbUtils } from '@matrixai/db'; -import { withF } from '@matrixai/resources'; +import * as resources from '@matrixai/resources'; import * as notificationsUtils from './utils'; import * as notificationsErrors from './errors'; import * as notificationsPB from '../proto/js/polykey/v1/notifications/notifications_pb'; @@ -76,8 +76,8 @@ class NotificationsManager { protected keyManager: KeyManager; protected nodeManager: NodeManager; protected nodeConnectionManager: NodeConnectionManager; - protected messageCap: number; + protected lock: Lock = new Lock(); /** * Top level stores MESSAGE_COUNT_KEY -> number (of messages) @@ -122,28 +122,25 @@ class NotificationsManager { public async start({ fresh = false, }: { fresh?: boolean } = {}): Promise { - this.logger.info(`Starting ${this.constructor.name}`); - if (fresh) { - await this.db.clear(this.notificationsDbPath); - } - // Getting latest ID and creating ID generator - let latestId: NotificationId | undefined; - // for await (const [k] of tran.iterator({ value: false }, [ - // ...this.nodeGraphBucketsDbPath, - // ])) { - // const keyStream = this.notificationsMessagesDb.createKeyStream({ - // limit: 1, - // reverse: true, - // }); - await withF( - [this.db.transaction()], - ([tran]) => async (tran) => tran.iterator({ limit: 1, reverse: true, value: false }, [...this.notificationsMessagesDbPath]) - } - for await (const o of keyStream) { - latestId = IdInternal.fromBuffer(o as Buffer); - } - this.notificationIdGenerator = createNotificationIdGenerator(latestId); - this.logger.info(`Started ${this.constructor.name}`); + await this.db.withTransactionF(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 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() { @@ -153,45 +150,21 @@ 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, - ): 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); - } - } - /** * Send a notification to another node * 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()), @@ -213,46 +186,50 @@ 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)!, - ); - 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 this.db.get( - this.notificationsDbDomain, - MESSAGE_COUNT_KEY, + public async receiveNotification(notification: Notification): Promise { + return await resources.withF( + [this.db.transaction(), this.lock.lock()], + async ([tran]) => { + const nodePerms = await this.acl.getNodePerm( + nodesUtils.decodeNodeId(notification.senderId)!, ); - if (numMessages === undefined) { - numMessages = 0; - await this.db.put(this.notificationsDbDomain, MESSAGE_COUNT_KEY, 0); + if (nodePerms === undefined) { + throw new notificationsErrors.ErrorNotificationsPermissionsNotFound(); } - if (numMessages >= this.messageCap) { - // Remove the oldest notification from notificationsMessagesDb - const oldestId = await this.getOldestNotificationId(); - await this.removeNotification(oldestId!); + // 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([ + ...this.notificationsDbPath, + MESSAGE_COUNT_KEY, + ]); + if (numMessages === undefined) { + numMessages = 0; + await tran.put([...this.notificationsDbPath, MESSAGE_COUNT_KEY], 0); + } + 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( + [...this.notificationsDbPath, MESSAGE_COUNT_KEY], + newNumMessages, + ); } - // 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, - ); - } - }); + }, + ); } /** @@ -268,29 +245,34 @@ class NotificationsManager { number?: number | 'all'; order?: 'newest' | 'oldest'; } = {}): Promise> { - let notificationIds: Array; - if (unread === true) { - notificationIds = await this.getNotificationIds('unread'); - } else { - notificationIds = await this.getNotificationIds('all'); - } + return await resources.withF( + [this.db.transaction(), this.lock.lock()], + async ([tran]) => { + let notificationIds: Array; + if (unread) { + notificationIds = await this.getNotificationIds('unread', tran); + } else { + notificationIds = await this.getNotificationIds('all', tran); + } - if (order === 'newest') { - notificationIds.reverse(); - } + if (order === 'newest') { + notificationIds.reverse(); + } - if (number === 'all' || number > notificationIds.length) { - number = notificationIds.length; - } - notificationIds = notificationIds.slice(0, number); + if (number === 'all' || number > notificationIds.length) { + number = notificationIds.length; + } + notificationIds = notificationIds.slice(0, number); - const notifications: Array = []; - for (const id of notificationIds) { - const notification = await this.readNotificationById(id); - notifications.push(notification!); - } + const notifications: Array = []; + for (const id of notificationIds) { + const notification = await this.readNotificationById(id, tran); + notifications.push(notification!); + } - return notifications; + return notifications; + }, + ); } /** @@ -301,134 +283,135 @@ class NotificationsManager { public async findGestaltInvite( fromNode: NodeId, ): Promise { - const notifications = await this.getNotifications('all'); - for (const notification of notifications) { - if ( - notification.data.type === 'GestaltInvite' && - nodesUtils.decodeNodeId(notification.senderId)!.equals(fromNode) - ) { - return notification; - } - } + return await resources.withF( + [this.db.transaction(), this.lock.lock()], + async ([tran]) => { + const notifications = await this.getNotifications('all', tran); + for (const notification of notifications) { + if ( + notification.data.type === 'GestaltInvite' && + nodesUtils.decodeNodeId(notification.senderId)!.equals(fromNode) + ) { + return notification; + } + } + }, + ); } /** * 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, - ); - if (numMessages !== undefined) { - for (const id of notificationIds) { - await this.removeNotification(id); + public async clearNotifications(): Promise { + await resources.withF( + [this.db.transaction(), this.lock.lock()], + async ([tran]) => { + const notificationIds = await this.getNotificationIds('all', tran); + const numMessages = await tran.get([ + ...this.notificationsDbPath, + MESSAGE_COUNT_KEY, + ]); + 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 = []; + // This.notificationsMessagesDb.createValueStream() + 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, + ); } } From 7cce9864a443ca3822d5cc7436ec0e5365de3e36 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 11 May 2022 15:17:48 +1000 Subject: [PATCH 15/74] fix: integrating db changes into `Discovery` I opted not to use transactions for the most part. Adding things to the queue has to be handled with locking anyway so I opted to rely on that istead. This still bears testing though. --- src/discovery/Discovery.ts | 486 ++++++++++++++++++------------------- 1 file changed, 234 insertions(+), 252 deletions(-) diff --git a/src/discovery/Discovery.ts b/src/discovery/Discovery.ts index a6d6c1129..80b4b43f7 100644 --- a/src/discovery/Discovery.ts +++ b/src/discovery/Discovery.ts @@ -1,4 +1,4 @@ -import type { DB, DBTransaction, KeyPath, LevelPath } 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'; @@ -17,7 +17,6 @@ import type { Sigchain } from '../sigchain'; import type { KeyManager } from '../keys'; import type { ClaimIdEncoded, Claim, ClaimLinkIdentity } from '../claims/types'; import type { ChainData } from '../sigchain/types'; -import { Mutex } from 'async-mutex'; import Logger from '@matrixai/logger'; import { CreateDestroyStartStop, @@ -25,17 +24,15 @@ import { status, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { IdInternal } from '@matrixai/id'; -import { withF } from '@matrixai/resources'; -import { Lock, LockBox } from '@matrixai/async-locks'; -import { utils as dbUtils } from '@matrixai/db'; +import { Lock } from '@matrixai/async-locks'; import * as idUtils from '@matrixai/id/dist/utils'; 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( @@ -93,10 +90,9 @@ class Discovery { 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 lock: Lock = new Lock(); public constructor({ keyManager, @@ -130,60 +126,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 +175,192 @@ 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 { 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(); + } + await this.queuePlug.p; + } + if (this[status] === 'stopping') { + break; + } + + // Processing queue + for await (const [key, value] of this.db.iterator( + {}, + this.discoveryQueueDbPath, + )) { + const vertexId = IdInternal.fromBuffer(key) as DiscoveryQueueId; + const vertex = await this.db.deserializeDecrypt( + value, + false, + ); + 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 +374,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,145 +386,41 @@ 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; + break; + default: + never(); } - } else { - if (!(this[status] === 'stopping')) { - this.queuePlugRelease = await this.queuePlug.acquire(); - } - 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. - */ - protected async runDiscoveryQueue() { - for await (const _ of this.discoveryQueue) { - // Empty - } - } - /** * Simple check for whether the Discovery Queue is empty. Uses a * 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 +429,25 @@ 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 this.lock.withF(async () => { + await this.db.withTransactionF(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, - ); + const discoveryQueueId = this.discoveryQueueIdGenerator(); + await tran.put( + [...this.discoveryQueueDbDomain, idUtils.toBuffer(discoveryQueueId)], + gestaltKey, + ); + }); }); - if (this.queuePlugRelease != null) { - this.queuePlugRelease(); - this.queuePlugRelease = undefined; - } + this.queuePlug.resolveP(); } /** @@ -478,9 +455,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), + ]); }); } From 9c7d649ae85a669324e8112c7b6889b8915b0680 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Thu, 12 May 2022 18:36:24 +1000 Subject: [PATCH 16/74] fix: integrating db changes into `Sigchain` --- src/sigchain/Sigchain.ts | 425 ++++++++++++++------------------ tests/sigchain/Sigchain.test.ts | 9 +- 2 files changed, 191 insertions(+), 243 deletions(-) diff --git a/src/sigchain/Sigchain.ts b/src/sigchain/Sigchain.ts index 19baf94cf..0a7f8bb65 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, LevelPath } from '@matrixai/db'; import type { ChainDataEncoded } from './types'; import type { ClaimData, @@ -12,11 +12,12 @@ 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 { withF } from '@matrixai/resources'; import * as sigchainErrors from './errors'; import * as claimsUtils from '../claims/utils'; @@ -26,30 +27,22 @@ 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; + // 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 +78,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 +119,15 @@ 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( + f: (tran: DBTransaction) => Promise, + ): Promise { + return withF([this.db.transaction()], ([tran]) => f(tran)); } /** @@ -220,36 +169,28 @@ 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]; + if (tran == null) { + return this.withTransactionF(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 + const claimId = this.generateClaimId(); + await tran.put([...this.sigchainClaimsDbPath, claimId.toBuffer()], claim); + await tran.put( + [...this.sigchainMetadataDbPath, this.sequenceNumberKey], + newSequenceNumber, + ); + return [claimId, claim]; } /** @@ -261,34 +202,33 @@ 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 { + if (tran == null) { + return this.withTransactionF(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( + [...this.sigchainClaimsDbPath, this.generateClaimId().toBuffer()], + claim, + ); + await tran.put( + [...this.sigchainMetadataDbPath, this.sequenceNumberKey], + expectedSequenceNumber, + ); } /** @@ -298,19 +238,23 @@ 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; + if (tran == null) { + return this.withTransactionF(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 +264,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 +287,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 +314,41 @@ 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, + public async getSequenceNumber(tran?: DBTransaction): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => + this.getSequenceNumber(tran), ); - // 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; - }); + } + 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); - } - }); + public async getHashPrevious(tran?: DBTransaction): Promise { + if (tran == null) { + return this.withTransactionF(async (tran) => this.getHashPrevious(tran)); + } + 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 +357,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/tests/sigchain/Sigchain.test.ts b/tests/sigchain/Sigchain.test.ts index b6ff170ef..e36a70e10 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(); From 52fca024330044bc5a3cdb9510f21272806041c0 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 13 May 2022 10:18:05 +1000 Subject: [PATCH 17/74] build: updated dependencies and added incremental build --- .eslintrc | 14 +- .npmignore | 1 + package-lock.json | 17892 +++++++++++++++++++++++++++++++++++--------- package.json | 46 +- shell.nix | 8 +- tsconfig.json | 2 + 6 files changed, 14381 insertions(+), 3582 deletions(-) diff --git a/.eslintrc b/.eslintrc index c8db5d863..5b6e8f753 100644 --- a/.eslintrc +++ b/.eslintrc @@ -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": 2021 + "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 7feb7902b..6bb02a31f 100644 --- a/.npmignore +++ b/.npmignore @@ -13,3 +13,4 @@ /benches /build /builds +/dist/tsbuildinfo diff --git a/package-lock.json b/package-lock.json index 9ebc8bfbb..ed3d302d6 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.16.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz", - "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==", + "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": { @@ -626,344 +12287,356 @@ "@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.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "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.15.7", + "@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,55 +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" } }, - "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.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } + "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 }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "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": { @@ -1461,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", @@ -1537,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", @@ -1561,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", @@ -1583,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", @@ -1600,75 +13344,113 @@ } } }, + "@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.7.1", - "resolved": "https://registry.npmjs.org/@matrixai/async-init/-/async-init-1.7.1.tgz", - "integrity": "sha512-3ELRuEn6AoC3e0b4QccA+NxZl0LilyjYeu6a3Pf9VUVB89EepnNKsk/Afb9qa+B5LvLQwmgHtg4r9VwRpQpnQA==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@matrixai/async-init/-/async-init-1.7.3.tgz", + "integrity": "sha512-Sf3q5ODhVJqrYiAdGXmwj606956lgEMKGM9LMFU5scIOh13WokHo3GthjB1yh/umCV75NYvHJn60R9gnudVZ3Q==", "requires": { - "@matrixai/async-locks": "^2.2.0", - "@matrixai/errors": "^1.0.1" + "@matrixai/async-locks": "^2.2.4", + "@matrixai/errors": "^1.1.1" } }, "@matrixai/async-locks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.2.0.tgz", - "integrity": "sha512-i0a551EUMhD1WKpaAyhBUt83ckbOxPB4MlOH8VDzeDyPMAtLI9egCqf3HWOvhN0rSjoH97EmzmfxyAeAgiQzTw==", + "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.0.1", - "@matrixai/resources": "^1.0.0", + "@matrixai/errors": "^1.1.1", + "@matrixai/resources": "^1.1.3", "async-mutex": "^0.3.2" } }, "@matrixai/db": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-3.3.1.tgz", - "integrity": "sha512-EQulm82sBhw1WRhOzzWMoij1SwpjAQHgyokxleTwFHoAnDPMi4WVy4AIxd2lJMPOhhzEFQxCqQmmMYhZWwYAPg==", - "requires": { - "@matrixai/async-init": "^1.7.0", - "@matrixai/errors": "^1.0.1", - "@matrixai/logger": "^2.1.0", - "@matrixai/resources": "^1.0.0", - "@matrixai/workers": "^1.3.0", + "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", "threads": "^1.6.5" } }, "@matrixai/errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@matrixai/errors/-/errors-1.0.1.tgz", - "integrity": "sha512-9NbIm3rPMkZz+Ma5tfKduVCWfvYzdHlO89u9mBap7FzJqXkl4yoENjMZm5Do6PvhtIYtRcm6+eTgWvHd6pkdGg==", + "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" } }, "@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.0.0", - "resolved": "https://registry.npmjs.org/@matrixai/resources/-/resources-1.0.0.tgz", - "integrity": "sha512-B1ZkySZwOZTIzhK+YTN4HifOTd1dk1ifDUV8/8WgGho2nUZzIMYms7iDmW/ZHUCkqvWupKY6AYvfwnKBOJJnWg==" + "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.3.1", - "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.3.1.tgz", - "integrity": "sha512-AXI37aZ7gSqS5PpUCG7/yfNcnWNYiQUp4yFBY1Z9lKk0zrkQzND1zPjDuJ2E7t6E1a4rwa8vtysj5TVeMCA8jw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@matrixai/workers/-/workers-1.3.3.tgz", + "integrity": "sha512-ID1sSJDXjM0hdWC10euWGcFofuys7+IDP+XTBh8Gq6jirn18xJs71wSy357qxLVSa7mL00qRJJfW6rljcFUK4A==", "requires": { - "@matrixai/async-init": "^1.7.0", - "@matrixai/errors": "^1.0.1", - "@matrixai/logger": "^2.1.0", + "@matrixai/async-init": "^1.7.3", + "@matrixai/errors": "^1.1.1", + "@matrixai/logger": "^2.1.1", "threads": "^1.6.5" } }, @@ -1698,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", @@ -1708,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" @@ -1752,9 +13588,9 @@ "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", @@ -1765,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" @@ -1784,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" @@ -1802,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": { @@ -1817,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": { @@ -1841,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": { @@ -1862,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", @@ -1872,9 +13713,9 @@ } }, "@types/node": { - "version": "16.11.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.29.tgz", - "integrity": "sha512-9dDdonLyPJQJ/kdOlDxAah+bTI+u2ccF3k62FErhquDuggoCX6piWez7j7o6yNE+rP2IRcZVQ6Tw4N0P38+rWA==" + "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", @@ -1885,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": { @@ -1913,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": "*", @@ -1929,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", @@ -1966,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" @@ -1976,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", @@ -2034,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" @@ -2044,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": { @@ -2082,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": { @@ -2095,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", @@ -2129,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", @@ -2142,14 +13984,6 @@ "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": { @@ -2158,12 +13992,12 @@ "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": { @@ -2239,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" } @@ -2276,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", @@ -2330,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", @@ -2362,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", @@ -2402,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", @@ -2414,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": { @@ -2464,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" } }, @@ -2480,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": { @@ -2487,71 +14311,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "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", @@ -2628,15 +14392,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" } }, @@ -2673,23 +14437,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", @@ -2711,24 +14458,15 @@ "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.1", @@ -2744,32 +14482,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": { @@ -2799,15 +14511,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": { @@ -2817,9 +14529,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": { @@ -2832,34 +14544,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", @@ -2869,11 +14558,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": { @@ -2894,29 +14599,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": { @@ -2933,12 +14628,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", @@ -2965,13 +14654,7 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true } - } - }, - "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", @@ -2979,12 +14662,12 @@ "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": { @@ -3003,13 +14686,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", @@ -3043,11 +14722,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": { @@ -3061,21 +14740,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", @@ -3112,39 +14791,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", @@ -3173,59 +14846,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", @@ -3257,9 +14885,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": { @@ -3286,9 +14914,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", @@ -3296,9 +14924,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", @@ -3318,9 +14946,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" } @@ -3336,22 +14964,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", @@ -3365,42 +14992,30 @@ } }, "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": { - "@matrixai/db": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-1.2.1.tgz", - "integrity": "sha512-1W8TORmRX3q3NugZFn0FTgI0mo/n0nWBTXHKXwwPfxtdyNfi18JCj3HVCwWdToOo87ypnS/mqLDIUTSHbF7F3Q==", - "requires": { - "@matrixai/async-init": "^1.6.0", - "@matrixai/logger": "^2.1.0", - "@matrixai/workers": "^1.2.5", - "abstract-leveldown": "^7.2.0", - "async-mutex": "^0.3.1", - "level": "7.0.1", - "levelup": "^5.1.1", - "sublevel-prefixer": "^1.0.0", - "subleveldown": "^6.0.1", - "threads": "^1.6.5", - "ts-custom-error": "^3.2.0" - } + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" } } }, @@ -3413,15 +15028,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", @@ -3445,30 +15051,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": { @@ -3484,8 +15102,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", @@ -3507,9 +15124,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": { @@ -3542,13 +15159,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", @@ -3561,62 +15171,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", @@ -3629,6 +15225,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", @@ -3639,33 +15250,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" @@ -3677,11 +15302,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", @@ -3689,15 +15317,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", @@ -3706,14 +15325,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", @@ -3737,14 +15363,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": { @@ -3804,22 +15429,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", @@ -3827,14 +15443,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": { @@ -3864,9 +15480,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" @@ -3889,12 +15505,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": { @@ -3904,22 +15528,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": { @@ -3938,9 +15554,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 } } @@ -3955,9 +15571,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 } } @@ -3973,140 +15589,30 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "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 - } + }, + "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", @@ -4114,103 +15620,15 @@ "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==", + "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": { - "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" - } - } + "@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": { @@ -4225,17 +15643,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", @@ -4243,6 +15661,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": { @@ -4323,15 +15752,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": { @@ -4345,15 +15768,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", @@ -4412,14 +15826,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": { @@ -4439,12 +15845,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", @@ -4467,26 +15889,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", @@ -4507,8 +15909,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", @@ -4527,13 +15928,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", @@ -4544,12 +15942,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", @@ -4570,12 +15962,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": { @@ -4585,28 +15977,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": { @@ -4618,13 +16010,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", @@ -4654,14 +16039,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": { @@ -4673,9 +16050,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", @@ -4683,10 +16060,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", @@ -4702,64 +16087,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", @@ -4770,12 +16097,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", @@ -4814,9 +16135,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", @@ -4824,9 +16145,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": { @@ -4844,9 +16165,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==" + "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", @@ -4867,9 +16188,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", @@ -4923,38 +16244,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", @@ -4989,50 +16281,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", @@ -5041,38 +16298,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", @@ -5080,10 +16305,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", @@ -5101,9 +16329,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", @@ -5112,9 +16340,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" } @@ -5124,15 +16352,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", @@ -5149,14 +16368,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": { @@ -5180,29 +16402,13 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "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, + }, + "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==", "requires": { - "is-docker": "^2.0.0" + "call-bind": "^1.0.2" } }, "isarray": { @@ -5216,16 +16422,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", @@ -5237,25 +16437,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" } }, @@ -5296,20 +16496,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", @@ -5317,16 +16509,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", @@ -5337,44 +16576,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", @@ -5383,135 +16605,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", @@ -5522,6 +16730,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", @@ -5540,17 +16763,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", @@ -5561,6 +16793,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", @@ -5579,27 +16826,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", @@ -5610,6 +16866,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", @@ -5628,88 +16899,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", @@ -5720,6 +16998,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", @@ -5749,27 +17042,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", @@ -5780,6 +17082,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", @@ -5798,22 +17115,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", @@ -5824,6 +17150,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", @@ -5842,12 +17183,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": "*" } }, @@ -5855,42 +17196,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", @@ -5901,6 +17256,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", @@ -5919,44 +17289,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", @@ -5967,6 +17347,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", @@ -5985,40 +17380,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", @@ -6029,17 +17428,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", @@ -6054,89 +17457,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", @@ -6147,6 +17519,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", @@ -6154,9 +17541,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" @@ -6174,19 +17561,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", @@ -6197,6 +17593,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", @@ -6215,23 +17626,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": { @@ -6244,6 +17664,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,20 +17697,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", @@ -6286,6 +17730,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", @@ -6304,14 +17763,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": { @@ -6321,9 +17780,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" @@ -6332,9 +17791,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", @@ -6390,14 +17849,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": { @@ -6424,13 +17875,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", @@ -6446,22 +17894,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", @@ -6525,14 +17959,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", @@ -6592,9 +18018,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": { @@ -6612,11 +18038,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", @@ -6624,17 +18049,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", @@ -6672,33 +18102,18 @@ "dev": true }, "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "requires": { - "tmpl": "1.0.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=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" + "tmpl": "1.0.5" } }, "marked": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.14.tgz", - "integrity": "sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==", + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.15.tgz", + "integrity": "sha512-esX5lPdTfG4p8LDkv+obbRCyOKzB+820ZZyMOXJZygZBHrH9b3xXR64X4kT3sPe9Nx8qQXbmcz6kFSMt4Nfk6Q==", "dev": true }, "md5.js": { @@ -6724,28 +18139,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": { @@ -6755,22 +18170,29 @@ "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": { +<<<<<<< HEAD "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, +>>>>>>> 55e00188 (build: updated dependencies and added incremental build) "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", @@ -6780,6 +18202,7 @@ "minimist": "^1.2.5" } }, +<<<<<<< HEAD "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", @@ -6806,6 +18229,8 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, +======= +>>>>>>> 55e00188 (build: updated dependencies and added incremental build) "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -6822,6 +18247,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": { @@ -6830,9 +18266,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", @@ -6844,25 +18280,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", @@ -6970,9 +18387,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", @@ -6990,38 +18431,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-releases": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", - "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", + "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", @@ -7029,20 +18444,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": { @@ -7083,62 +18490,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", @@ -7160,15 +18521,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", @@ -7216,18 +18568,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", @@ -7297,12 +18637,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", @@ -7350,9 +18684,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": { @@ -7361,13 +18695,10 @@ "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.6.0", @@ -7392,6 +18723,31 @@ "tslib": "2.3.1" }, "dependencies": { + "@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 + }, + "@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, + "requires": { + "@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", @@ -7402,6 +18758,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", @@ -7416,6 +18787,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true } } }, @@ -7444,6 +18821,15 @@ "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", @@ -7454,21 +18840,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 }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, "semver": { "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", @@ -7478,45 +18870,17 @@ "lru-cache": "^6.0.0" } }, - "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": { - "has-flag": "^4.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "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": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "has-flag": "^4.0.0" } } } }, - "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.1.4", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", @@ -7536,6 +18900,34 @@ "simple-get": "^3.0.3", "tar-fs": "^2.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": { @@ -7545,9 +18937,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": { @@ -7560,22 +18952,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", @@ -7597,6 +18991,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", @@ -7662,56 +19076,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", @@ -7729,36 +19099,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": { @@ -7768,29 +19139,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" @@ -7804,49 +19175,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": { @@ -7864,10 +19211,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": { @@ -7879,12 +19226,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", @@ -7908,12 +19249,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", @@ -7936,168 +19271,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", @@ -8119,29 +19298,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", @@ -8164,13 +19320,6 @@ "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.10.1", "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", @@ -8193,9 +19342,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": { @@ -8203,248 +19352,41 @@ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "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==", - "requires": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "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=", - "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==", - "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, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.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 + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, - "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" - } + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true }, - "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==", + "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 }, - "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==", + "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, "requires": { - "extend-shallow": "^3.0.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, "sprintf-js": { @@ -8470,27 +19412,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", @@ -8532,6 +19453,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", @@ -8543,40 +19472,51 @@ } }, "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": { @@ -8593,12 +19533,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", @@ -8611,24 +19545,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": "6.0.1", - "resolved": "https://registry.npmjs.org/subleveldown/-/subleveldown-6.0.1.tgz", - "integrity": "sha512-Cnf+cn2wISXU2xflY1SFIqfX4hG2d6lFk2P5F8RDQLmiqN9Ir4ExNfUFH6xnmizMseM/t+nMsDUKjN9Kw6ShFA==", - "requires": { - "abstract-leveldown": "^7.2.0", - "encoding-down": "^7.1.0", - "inherits": "^2.0.3", - "level-option-wrap": "^1.1.0", - "levelup": "^5.1.1", - "reachdown": "^1.1.0" - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -8665,40 +19581,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", @@ -8764,9 +19658,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": { @@ -8800,44 +19694,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", @@ -8856,6 +19712,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": { @@ -8873,27 +19737,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" @@ -8902,9 +19764,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", @@ -8918,15 +19780,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", @@ -8936,14 +19793,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": { @@ -8965,9 +19822,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", @@ -9011,9 +19868,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": { @@ -9059,71 +19916,26 @@ } }, "typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "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" - }, - "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==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "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" } }, @@ -9171,22 +19983,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": { @@ -9194,46 +19994,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", @@ -9242,18 +20002,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", @@ -9290,10 +20038,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", @@ -9309,16 +20063,6 @@ } } }, - "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", @@ -9350,12 +20094,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": { @@ -9410,12 +20154,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 - }, "wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -9441,11 +20179,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": { @@ -9466,10 +20241,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": { "version": "1.0.1", @@ -9491,8 +20267,7 @@ "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", @@ -9504,7 +20279,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", @@ -9513,13 +20287,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 bcd800011..032299e22 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "scripts": "dist/workers/polykeyWorker.js" }, "scripts": { + "prepare": "tsc -p ./tsconfig.build.json", "build": "rimraf ./dist && 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/;", "postversion": "npm install --package-lock-only --ignore-scripts --silent", @@ -72,15 +73,15 @@ "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.7.1", - "@matrixai/async-locks": "^2.2.0", - "@matrixai/db": "^3.2.3", - "@matrixai/errors": "^1.0.1", - "@matrixai/id": "^3.3.2", - "@matrixai/logger": "^2.1.0", - "@matrixai/resources": "^1.0.0", - "@matrixai/workers": "^1.3.1", + "@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", @@ -88,7 +89,7 @@ "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", @@ -112,7 +113,7 @@ "@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": "^16.11.7", "@types/node-forge": "^0.9.7", @@ -120,27 +121,26 @@ "@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.4.0", "pkg": "5.6.0", - "prettier": "^2.2.1", - "ts-jest": "^26.4.4", + "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", - "typescript-cached-transpile": "0.0.6" + "typescript": "^4.5.2" } } diff --git a/shell.nix b/shell.nix index 10f435f98..3b4bd595f 100644 --- a/shell.nix +++ b/shell.nix @@ -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/tsconfig.json b/tsconfig.json index 8e4424ab2..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, From 403be9e541852f972222dda7818ad7449ec7f651 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 13 May 2022 11:19:58 +1000 Subject: [PATCH 18/74] fix: integrating db changes into sessions --- jest.config.js | 2 +- src/sessions/SessionManager.ts | 113 +++++++++++--------------- tests/sessions/SessionManager.test.ts | 6 +- 3 files changed, 53 insertions(+), 68 deletions(-) diff --git a/jest.config.js b/jest.config.js index abb464811..9002d3d7b 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(compilerOptions.paths, { diff --git a/src/sessions/SessionManager.ts b/src/sessions/SessionManager.ts index 6ee4bbbc9..b05ccdf0c 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 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/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'; From 6b199d00476bb64344d765a0c007e2d481b94465 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 13 May 2022 15:11:28 +1000 Subject: [PATCH 19/74] fix: keymanager tests passing --- tests/keys/KeyManager.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 () => { From b0d6161d8ebd71fae21c55dc8937167211daed76 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 13 May 2022 15:18:59 +1000 Subject: [PATCH 20/74] fix: git tests passing --- tests/git/utils.test.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) 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(), + ); }); }); }); From 277c57748b196139bf47b5cc45551999ff2596c8 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 13 May 2022 16:12:51 +1000 Subject: [PATCH 21/74] fix: NodeGraph tests passing --- src/nodes/NodeConnectionManager.ts | 4 +-- src/nodes/NodeGraph.ts | 53 +++++++++++------------------- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/nodes/NodeConnectionManager.ts b/src/nodes/NodeConnectionManager.ts index 84e9ddfa9..23572a0c7 100644 --- a/src/nodes/NodeConnectionManager.ts +++ b/src/nodes/NodeConnectionManager.ts @@ -132,13 +132,13 @@ class NodeConnectionManager { return async () => { const connAndLock = await this.getConnection(targetNodeId); // Acquire the read lock and the release function - const release = connAndLock.lock.read(); + const [release] = await connAndLock.lock.read()(); // Resetting TTL timer connAndLock.timer?.refresh(); // Return tuple of [ResourceRelease, Resource] return [ async () => { - release(); + await release(); }, connAndLock.connection, ]; diff --git a/src/nodes/NodeGraph.ts b/src/nodes/NodeGraph.ts index f1f12e149..7cd35ee13 100644 --- a/src/nodes/NodeGraph.ts +++ b/src/nodes/NodeGraph.ts @@ -104,10 +104,7 @@ class NodeGraph { public async withTransactionF( f: (tran: DBTransaction) => Promise, ): Promise { - return withF( - [this.db.transaction()], - ([tran]) => f(tran), - ); + return withF([this.db.transaction()], ([tran]) => f(tran)); } /** @@ -116,20 +113,19 @@ class NodeGraph { * @returns Node Address of the target node */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) - public async getNode(nodeId: NodeId, tran?: DBTransaction): Promise { + public async getNode( + nodeId: NodeId, + tran?: DBTransaction, + ): Promise { if (tran == null) { - return this.withTransactionF(async (tran) => - this.getNode(nodeId, tran), - ); + 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, - ); + const bucket = await tran.get(bucketPath); if (bucket != null && nodeId in bucket) { return bucket[nodeId].address; } @@ -152,7 +148,10 @@ class NodeGraph { * @param bucketIndex */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) - public async getBucket(bucketIndex: number, tran?: DBTransaction): Promise { + public async getBucket( + bucketIndex: number, + tran?: DBTransaction, + ): Promise { if (tran == null) { return this.withTransactionF(async (tran) => this.getBucket(bucketIndex, tran), @@ -162,9 +161,7 @@ class NodeGraph { ...this.nodeGraphBucketsDbPath, lexi.pack(bucketIndex, 'hex'), ] as unknown as KeyPath; - const bucket = await tran.get( - bucketPath, - ); + 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 @@ -195,9 +192,7 @@ class NodeGraph { ...this.nodeGraphBucketsDbPath, bucketIndex, ] as unknown as KeyPath; - let bucket = await tran.get( - bucketPath, - ); + let bucket = await tran.get(bucketPath); if (bucket == null) { bucket = {}; } @@ -245,9 +240,7 @@ class NodeGraph { ...this.nodeGraphBucketsDbPath, bucketIndex, ] as unknown as KeyPath; - const bucket = await tran.get( - bucketPath, - ); + const bucket = await tran.get(bucketPath); if (bucket != null && nodeId in bucket) { bucket[nodeId].lastUpdated = new Date(); if (nodeAddress != null) { @@ -275,9 +268,7 @@ class NodeGraph { ...this.nodeGraphBucketsDbPath, bucketIndex, ] as unknown as KeyPath; - const bucket = await tran.get( - bucketPath - ); + const bucket = await tran.get(bucketPath); if (bucket == null) { return; } @@ -308,12 +299,10 @@ class NodeGraph { @ready(new nodesErrors.ErrorNodeGraphNotRunning()) public async getAllBuckets(tran?: DBTransaction): Promise> { if (tran == null) { - return this.withTransactionF(async (tran) => - this.getAllBuckets(tran), - ); + return this.withTransactionF(async (tran) => this.getAllBuckets(tran)); } const buckets: Array = []; - for await (const [v] of tran.iterator({ key: false }, [ + for await (const [, v] of tran.iterator({ keys: false }, [ ...this.nodeGraphBucketsDbPath, ])) { const bucket = dbUtils.deserialize(v); @@ -332,19 +321,17 @@ class NodeGraph { @ready(new nodesErrors.ErrorNodeGraphNotRunning()) public async refreshBuckets(tran?: DBTransaction): Promise { if (tran == null) { - return this.withTransactionF(async (tran) => - this.refreshBuckets(tran), - ); + return this.withTransactionF(async (tran) => this.refreshBuckets(tran)); } // Get a local copy of all the buckets - const buckets = await this.getAllBuckets(); + 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 = dbUtils.deserialize(k); + const hexBucketIndex = k.toString(); const hexBucketPath = [ ...this.nodeGraphBucketsDbPath, hexBucketIndex, From 4f4b4383d382cba9446c10b0a8f9128fe64f900f Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 13 May 2022 16:22:09 +1000 Subject: [PATCH 22/74] feat: adding transactions to service handlers --- src/PolykeyAgent.ts | 1 + src/client/service/agentLockAll.ts | 9 ++++++++- src/client/service/index.ts | 4 ++++ src/client/utils/utils.ts | 5 +++-- src/sessions/SessionManager.ts | 2 +- tests/nodes/NodeConnectionManager.lifecycle.test.ts | 2 +- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/PolykeyAgent.ts b/src/PolykeyAgent.ts index a72ba5f16..32be57de3 100644 --- a/src/PolykeyAgent.ts +++ b/src/PolykeyAgent.ts @@ -563,6 +563,7 @@ class PolykeyAgent { }); const clientService = createClientService({ pkAgent: this, + db: this.db, discovery: this.discovery, gestaltGraph: this.gestaltGraph, identitiesManager: this.identitiesManager, diff --git a/src/client/service/agentLockAll.ts b/src/client/service/agentLockAll.ts index 6f7eaba76..02caef2c1 100644 --- a/src/client/service/agentLockAll.ts +++ b/src/client/service/agentLockAll.ts @@ -1,17 +1,21 @@ +import type { DB } from '@matrixai/db'; import type * as grpc from '@grpc/grpc-js'; import type { Authenticate } from '../types'; import type { SessionManager } from '../../sessions'; import type Logger from '@matrixai/logger'; +import { withF } from '@matrixai/resources'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function agentLockAll({ authenticate, sessionManager, + db, logger, }: { authenticate: Authenticate; sessionManager: SessionManager; + db: DB; logger: Logger; }) { return async ( @@ -22,7 +26,10 @@ function agentLockAll({ const response = new utilsPB.EmptyMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - await sessionManager.resetKey(); + await withF( + [db.transaction()], + async ([tran]) => await sessionManager.resetKey(tran), + ); callback(null, response); return; } catch (e) { diff --git a/src/client/service/index.ts b/src/client/service/index.ts index 494c5088c..dc7ac4ff7 100644 --- a/src/client/service/index.ts +++ b/src/client/service/index.ts @@ -1,3 +1,4 @@ +import type { DB } from '@matrixai/db'; import type PolykeyAgent from '../../PolykeyAgent'; import type { KeyManager } from '../../keys'; import type { VaultManager } from '../../vaults'; @@ -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/utils/utils.ts b/src/client/utils/utils.ts index 3e2021cf9..f922128bb 100644 --- a/src/client/utils/utils.ts +++ b/src/client/utils/utils.ts @@ -3,8 +3,9 @@ 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'; diff --git a/src/sessions/SessionManager.ts b/src/sessions/SessionManager.ts index b05ccdf0c..f7e618a0b 100644 --- a/src/sessions/SessionManager.ts +++ b/src/sessions/SessionManager.ts @@ -154,7 +154,7 @@ class SessionManager { } protected async setupKey(bits: 128 | 192 | 256): Promise { - return withF([this.db.transaction()], async ([tran]) => { + return await withF([this.db.transaction()], async ([tran]) => { let key: Buffer | undefined; key = await tran.get([...this.sessionsDbPath, 'key'], true); if (key != null) { 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( From 9afde49cb5ab00cf426c511f095938cc0bffbcfa Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Fri, 13 May 2022 17:47:24 +1000 Subject: [PATCH 23/74] fix: fix for `GRPCServer` `http2Servers` hack This was throwing an error because the expected object structure changed. The typing is brittle here since we're going around typescript's back to get a private property. --- src/grpc/GRPCServer.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/grpc/GRPCServer.ts b/src/grpc/GRPCServer.ts index b7a0ac84c..fb9218e3a 100644 --- a/src/grpc/GRPCServer.ts +++ b/src/grpc/GRPCServer.ts @@ -74,8 +74,9 @@ class GRPCServer { } 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( @@ -199,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'), From 51bcaa277ca2c2ea38c2455ba2a2177321219e5f Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Mon, 16 May 2022 11:41:52 +1000 Subject: [PATCH 24/74] fix: Small test fixes --- src/PolykeyAgent.ts | 3 +-- tests/bin/utils.ts | 2 +- tests/client/utils.ts | 2 ++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/PolykeyAgent.ts b/src/PolykeyAgent.ts index 32be57de3..855b3f908 100644 --- a/src/PolykeyAgent.ts +++ b/src/PolykeyAgent.ts @@ -421,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, 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/utils.ts b/tests/client/utils.ts index c3cc7d25b..036257328 100644 --- a/tests/client/utils.ts +++ b/tests/client/utils.ts @@ -40,6 +40,8 @@ async function openTestClientServer({ grpcServerClient: pkAgent.grpcServerClient, grpcServerAgent: pkAgent.grpcServerAgent, fs: pkAgent.fs, + db: pkAgent.db, + logger: pkAgent.logger, }); const callCredentials = _secure From d51f282617b092d9b44886eec9575a0ef5a97f0f Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Mon, 16 May 2022 17:17:45 +1000 Subject: [PATCH 25/74] fix: Small fix for NotificationsManager tests --- tests/notifications/NotificationsManager.test.ts | 10 ++++------ tests/utils.ts | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 7 deletions(-) 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/utils.ts b/tests/utils.ts index c32329886..f6f76c538 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -13,6 +13,7 @@ import { IdInternal } from '@matrixai/id'; 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,16 @@ function generateRandomNodeId(): NodeId { return IdInternal.fromString(random); } -export { setupGlobalKeypair, 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 }; From 6266b7274829249cfa77466827855ba6d6481367 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Mon, 16 May 2022 17:18:06 +1000 Subject: [PATCH 26/74] fix: Small fix for Discovery tests --- src/discovery/Discovery.ts | 31 ++++++-- tests/discovery/Discovery.test.ts | 125 ++++-------------------------- 2 files changed, 37 insertions(+), 119 deletions(-) diff --git a/src/discovery/Discovery.ts b/src/discovery/Discovery.ts index 80b4b43f7..42d0fe154 100644 --- a/src/discovery/Discovery.ts +++ b/src/discovery/Discovery.ts @@ -26,6 +26,8 @@ import { 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'; @@ -92,6 +94,7 @@ class Discovery { protected visitedVertices = new Set(); protected discoveryProcess: Promise; protected queuePlug = promise(); + protected queueDrained = promise(); protected lock: Lock = new Lock(); public constructor({ @@ -184,28 +187,32 @@ class Discovery { * Async function for processing the Discovery Queue */ public async setupDiscoveryQueue(): Promise { + this.logger.debug('Setting up DiscoveryQueue'); while (true) { // 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 = await this.db.deserializeDecrypt( - value, - false, - ); + const vertex = DBUtils.deserialize(value); + this.logger.debug(`Processing vertex: ${vertex}`); const vertexGId = gestaltsUtils.ungestaltKey(vertex); switch (vertexGId.type) { case 'node': @@ -406,6 +413,13 @@ class Discovery { } } + /** + * Will resolve once the queue has drained + */ + public async waitForDrained(): Promise { + await this.queueDrained.p; + } + /** * Simple check for whether the Discovery Queue is empty. Uses a * transaction lock to ensure consistency. @@ -432,8 +446,9 @@ class Discovery { protected async pushKeyToDiscoveryQueue( gestaltKey: GestaltKey, ): Promise { - await this.lock.withF(async () => { - await this.db.withTransactionF(async (tran) => { + 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) { @@ -445,8 +460,8 @@ class Discovery { [...this.discoveryQueueDbDomain, idUtils.toBuffer(discoveryQueueId)], gestaltKey, ); - }); - }); + }, + ); this.queuePlug.resolveP(); } diff --git a/tests/discovery/Discovery.test.ts b/tests/discovery/Discovery.test.ts index 70c4641dd..abfcab85d 100644 --- a/tests/discovery/Discovery.test.ts +++ b/tests/discovery/Discovery.test.ts @@ -1,7 +1,6 @@ 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'; @@ -16,7 +15,6 @@ import { KeyManager } from '@/keys'; import { ACL } from '@/acl'; import { Sigchain } from '@/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 +249,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 +283,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 +317,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 +351,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 +392,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; From 5fa0bcd6da6b15d131e3a6293f6e74f1bca740e4 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 17 May 2022 11:17:19 +1000 Subject: [PATCH 27/74] fix: removing sigchain.transaction --- src/agent/service/nodesCrossSignClaim.ts | 248 +++++++++++------------ src/nodes/NodeManager.ts | 231 +++++++++++---------- 2 files changed, 245 insertions(+), 234 deletions(-) diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index 45af67a8d..59b9cac1a 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -28,136 +28,134 @@ function nodesCrossSignClaim({ ) => { const genClaims = grpcUtils.generatorDuplex(call, true); try { - await sigchain.transaction(async (sigchain) => { - 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(); - if (!intermediaryClaimMessage) { - throw new claimsErrors.ErrorUndefinedSinglySignedClaim(); - } - const intermediarySignature = intermediaryClaimMessage.getSignature(); - if (!intermediarySignature) { - throw new claimsErrors.ErrorUndefinedSignature(); - } + 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(); + if (!intermediaryClaimMessage) { + throw new claimsErrors.ErrorUndefinedSinglySignedClaim(); + } + const intermediarySignature = intermediaryClaimMessage.getSignature(); + 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 - const constructedIntermediaryClaim: ClaimIntermediary = { - payload: intermediaryClaimMessage.getPayload(), - signature: { + // 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 + const constructedIntermediaryClaim: ClaimIntermediary = { + payload: intermediaryClaimMessage.getPayload(), + signature: { + protected: intermediarySignature.getProtected(), + signature: intermediarySignature.getSignature(), + }, + }; + // Get the sender's node ID from the claim + const constructedEncodedClaim: ClaimEncoded = { + payload: intermediaryClaimMessage.getPayload(), + signatures: [ + { protected: intermediarySignature.getProtected(), signature: intermediarySignature.getSignature(), }, - }; - // Get the sender's node ID from the claim - const constructedEncodedClaim: ClaimEncoded = { - payload: intermediaryClaimMessage.getPayload(), - signatures: [ - { - protected: intermediarySignature.getProtected(), - signature: intermediarySignature.getSignature(), - }, - ], - }; - const decodedClaim = claimsUtils.decodeClaim(constructedEncodedClaim); - const payloadData = decodedClaim.payload.data; - if (payloadData.type !== 'node') { - throw new claimsErrors.ErrorNodesClaimType(); - } - const { - nodeId, - }: { - nodeId: NodeId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [['nodeId'], () => validationUtils.parseNodeId(value)], - () => value, - ); - }, - { - nodeId: payloadData.node1, - }, - ); - // Verify the claim - const senderPublicKey = await nodeManager.getPublicKey(nodeId); - const verified = await claimsUtils.verifyClaimSignature( - constructedEncodedClaim, - senderPublicKey, - ); - if (!verified) { - throw new claimsErrors.ErrorSinglySignedClaimVerificationFailed(); - } - // If verified, add your own signature to the received claim - const doublySignedClaim = await claimsUtils.signIntermediaryClaim({ - claim: constructedIntermediaryClaim, - privateKey: keyManager.getRootKeyPairPem().privateKey, - 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, - }); - // Should never be reached, but just for type safety - if (!doublySignedClaim.payload || !singlySignedClaim.payload) { - throw new claimsErrors.ErrorClaimsUndefinedClaimPayload(); - } - // Write both these claims to a message to send - const crossSignMessage = claimsUtils.createCrossSignMessage({ - singlySignedClaim, - doublySignedClaim, - }); - await genClaims.write(crossSignMessage); - // 4. We expect to receive our singly signed claim we sent to now be a - // doubly signed claim (signed by the other node). - const responseStatus = await genClaims.read(); - if (responseStatus.done) { - throw new claimsErrors.ErrorEmptyStream(); - } - const receivedResponse = responseStatus.value; - const receivedDoublySignedClaimMessage = - receivedResponse.getDoublySignedClaim(); - if (!receivedDoublySignedClaimMessage) { - throw new claimsErrors.ErrorUndefinedDoublySignedClaim(); - } - // Reconstruct the expected object from message - const constructedDoublySignedClaim: ClaimEncoded = { - payload: receivedDoublySignedClaimMessage.getPayload(), - signatures: receivedDoublySignedClaimMessage - .getSignaturesList() - .map((sMsg) => { - return { - protected: sMsg.getProtected(), - signature: sMsg.getSignature(), - }; - }), - }; - // Verify the doubly signed claim with both our public key, and the sender's - const verifiedDoubly = - (await claimsUtils.verifyClaimSignature( - constructedDoublySignedClaim, - keyManager.getRootKeyPairPem().publicKey, - )) && - (await claimsUtils.verifyClaimSignature( - constructedDoublySignedClaim, - senderPublicKey, - )); - if (!verifiedDoubly) { - throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed(); - } - // If verified, then we can safely add to our sigchain - await sigchain.addExistingClaim(constructedDoublySignedClaim); - // Close the stream - await genClaims.next(null); - return; + ], + }; + const decodedClaim = claimsUtils.decodeClaim(constructedEncodedClaim); + const payloadData = decodedClaim.payload.data; + if (payloadData.type !== 'node') { + throw new claimsErrors.ErrorNodesClaimType(); + } + const { + nodeId, + }: { + nodeId: NodeId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [['nodeId'], () => validationUtils.parseNodeId(value)], + () => value, + ); + }, + { + nodeId: payloadData.node1, + }, + ); + // Verify the claim + const senderPublicKey = await nodeManager.getPublicKey(nodeId); + const verified = await claimsUtils.verifyClaimSignature( + constructedEncodedClaim, + senderPublicKey, + ); + if (!verified) { + throw new claimsErrors.ErrorSinglySignedClaimVerificationFailed(); + } + // If verified, add your own signature to the received claim + const doublySignedClaim = await claimsUtils.signIntermediaryClaim({ + claim: constructedIntermediaryClaim, + privateKey: keyManager.getRootKeyPairPem().privateKey, + 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, + }); + // Should never be reached, but just for type safety + if (!doublySignedClaim.payload || !singlySignedClaim.payload) { + throw new claimsErrors.ErrorClaimsUndefinedClaimPayload(); + } + // Write both these claims to a message to send + const crossSignMessage = claimsUtils.createCrossSignMessage({ + singlySignedClaim, + doublySignedClaim, + }); + await genClaims.write(crossSignMessage); + // 4. We expect to receive our singly signed claim we sent to now be a + // doubly signed claim (signed by the other node). + const responseStatus = await genClaims.read(); + if (responseStatus.done) { + throw new claimsErrors.ErrorEmptyStream(); + } + const receivedResponse = responseStatus.value; + const receivedDoublySignedClaimMessage = + receivedResponse.getDoublySignedClaim(); + if (!receivedDoublySignedClaimMessage) { + throw new claimsErrors.ErrorUndefinedDoublySignedClaim(); + } + // Reconstruct the expected object from message + const constructedDoublySignedClaim: ClaimEncoded = { + payload: receivedDoublySignedClaimMessage.getPayload(), + signatures: receivedDoublySignedClaimMessage + .getSignaturesList() + .map((sMsg) => { + return { + protected: sMsg.getProtected(), + signature: sMsg.getSignature(), + }; + }), + }; + // Verify the doubly signed claim with both our public key, and the sender's + const verifiedDoubly = + (await claimsUtils.verifyClaimSignature( + constructedDoublySignedClaim, + keyManager.getRootKeyPairPem().publicKey, + )) && + (await claimsUtils.verifyClaimSignature( + constructedDoublySignedClaim, + senderPublicKey, + )); + if (!verifiedDoubly) { + throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed(); + } + // If verified, then we can safely add to our sigchain + await sigchain.addExistingClaim(constructedDoublySignedClaim); + // Close the stream + await genClaims.next(null); + return; } catch (e) { await genClaims.throw(e); logger.error(e); diff --git a/src/nodes/NodeManager.ts b/src/nodes/NodeManager.ts index 8035f0bfa..61820d706 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'; @@ -182,120 +182,125 @@ 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); + }, + ); } /** @@ -306,6 +311,7 @@ class NodeManager { public async getNodeAddress( nodeId: NodeId, ): Promise { + // FIXME: use tran return await this.nodeGraph.getNode(nodeId); } @@ -315,6 +321,7 @@ class NodeManager { * @returns true if the node exists in the table, false otherwise */ public async knowsNode(targetNodeId: NodeId): Promise { + // FIXME: use tran return await this.nodeGraph.knowsNode(targetNodeId); } @@ -322,6 +329,7 @@ class NodeManager { * Gets the specified bucket from the NodeGraph */ public async getBucket(bucketIndex: number): Promise { + // FIXME: use tran return await this.nodeGraph.getBucket(bucketIndex); } @@ -332,6 +340,7 @@ class NodeManager { nodeId: NodeId, nodeAddress: NodeAddress, ): Promise { + // FIXME: use tran return await this.nodeGraph.setNode(nodeId, nodeAddress); } @@ -342,6 +351,7 @@ class NodeManager { nodeId: NodeId, nodeAddress?: NodeAddress, ): Promise { + // FIXME: use tran return await this.nodeGraph.updateNode(nodeId, nodeAddress); } @@ -349,6 +359,7 @@ class NodeManager { * Removes a node from the NodeGraph */ public async unsetNode(nodeId: NodeId): Promise { + // FIXME: use tran return await this.nodeGraph.unsetNode(nodeId); } @@ -356,6 +367,7 @@ class NodeManager { * Gets all buckets from the NodeGraph */ public async getAllBuckets(): Promise> { + // FIXME: use tran return await this.nodeGraph.getAllBuckets(); } @@ -364,6 +376,7 @@ class NodeManager { * to the new node ID. */ public async refreshBuckets(): Promise { + // FIXME: use tran return await this.nodeGraph.refreshBuckets(); } } From 6b1a0ae5a3c4844508d8e1c5cc4f0e96bc77f89e Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 17 May 2022 12:00:35 +1000 Subject: [PATCH 28/74] fix: added locking back into sigchain Sequence numbers and claim ids needed locking due to serialisation concerns --- src/PolykeyAgent.ts | 1 + src/agent/service/index.ts | 4 + src/agent/service/nodesCrossSignClaim.ts | 272 ++++++++++++----------- src/sigchain/Sigchain.ts | 75 ++++--- tests/nodes/NodeManager.test.ts | 10 +- tests/sigchain/Sigchain.test.ts | 38 +++- 6 files changed, 221 insertions(+), 179 deletions(-) diff --git a/src/PolykeyAgent.ts b/src/PolykeyAgent.ts index 855b3f908..b172f1fd2 100644 --- a/src/PolykeyAgent.ts +++ b/src/PolykeyAgent.ts @@ -549,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, diff --git a/src/agent/service/index.ts b/src/agent/service/index.ts index caa8c60ed..6342c2ba5 100644 --- a/src/agent/service/index.ts +++ b/src/agent/service/index.ts @@ -1,3 +1,4 @@ +import type { DB } from '@matrixai/db'; import type KeyManager from '../../keys/KeyManager'; import type VaultManager from '../../vaults/VaultManager'; import type NodeGraph from '../../nodes/NodeGraph'; @@ -25,9 +26,11 @@ import * as agentUtils from '../utils'; function createService({ proxy, + db, logger = new Logger(createService.name), ...containerRest }: { + db: DB; keyManager: KeyManager; vaultManager: VaultManager; nodeConnectionManager: NodeConnectionManager; @@ -43,6 +46,7 @@ function createService({ const connectionInfoGet = agentUtils.connectionInfoGetter(proxy); const container = { ...containerRest, + db, logger, connectionInfoGet: connectionInfoGet, }; diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index 59b9cac1a..b21ed882c 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -1,23 +1,29 @@ 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 type Logger from '@matrixai/logger'; -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 { withF } from '@matrixai/resources'; +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; @@ -28,134 +34,138 @@ function nodesCrossSignClaim({ ) => { const genClaims = grpcUtils.generatorDuplex(call, true); try { - 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(); - if (!intermediaryClaimMessage) { - throw new claimsErrors.ErrorUndefinedSinglySignedClaim(); - } - const intermediarySignature = intermediaryClaimMessage.getSignature(); - 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 - const constructedIntermediaryClaim: ClaimIntermediary = { - payload: intermediaryClaimMessage.getPayload(), - signature: { - protected: intermediarySignature.getProtected(), - signature: intermediarySignature.getSignature(), - }, - }; - // Get the sender's node ID from the claim - const constructedEncodedClaim: ClaimEncoded = { - payload: intermediaryClaimMessage.getPayload(), - signatures: [ - { + await withF([db.transaction()], async ([tran]) => { + 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(); + if (!intermediaryClaimMessage) { + throw new claimsErrors.ErrorUndefinedSinglySignedClaim(); + } + const intermediarySignature = intermediaryClaimMessage.getSignature(); + 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 + const constructedIntermediaryClaim: ClaimIntermediary = { + payload: intermediaryClaimMessage.getPayload(), + signature: { protected: intermediarySignature.getProtected(), signature: intermediarySignature.getSignature(), }, - ], - }; - const decodedClaim = claimsUtils.decodeClaim(constructedEncodedClaim); - const payloadData = decodedClaim.payload.data; - if (payloadData.type !== 'node') { - throw new claimsErrors.ErrorNodesClaimType(); - } - const { - nodeId, - }: { - nodeId: NodeId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [['nodeId'], () => validationUtils.parseNodeId(value)], - () => value, - ); - }, - { - nodeId: payloadData.node1, - }, - ); - // Verify the claim - const senderPublicKey = await nodeManager.getPublicKey(nodeId); - const verified = await claimsUtils.verifyClaimSignature( - constructedEncodedClaim, - senderPublicKey, - ); - if (!verified) { - throw new claimsErrors.ErrorSinglySignedClaimVerificationFailed(); - } - // If verified, add your own signature to the received claim - const doublySignedClaim = await claimsUtils.signIntermediaryClaim({ - claim: constructedIntermediaryClaim, - privateKey: keyManager.getRootKeyPairPem().privateKey, - 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, - }); - // Should never be reached, but just for type safety - if (!doublySignedClaim.payload || !singlySignedClaim.payload) { - throw new claimsErrors.ErrorClaimsUndefinedClaimPayload(); - } - // Write both these claims to a message to send - const crossSignMessage = claimsUtils.createCrossSignMessage({ - singlySignedClaim, - doublySignedClaim, - }); - await genClaims.write(crossSignMessage); - // 4. We expect to receive our singly signed claim we sent to now be a - // doubly signed claim (signed by the other node). - const responseStatus = await genClaims.read(); - if (responseStatus.done) { - throw new claimsErrors.ErrorEmptyStream(); - } - const receivedResponse = responseStatus.value; - const receivedDoublySignedClaimMessage = - receivedResponse.getDoublySignedClaim(); - if (!receivedDoublySignedClaimMessage) { - throw new claimsErrors.ErrorUndefinedDoublySignedClaim(); - } - // Reconstruct the expected object from message - const constructedDoublySignedClaim: ClaimEncoded = { - payload: receivedDoublySignedClaimMessage.getPayload(), - signatures: receivedDoublySignedClaimMessage - .getSignaturesList() - .map((sMsg) => { - return { - protected: sMsg.getProtected(), - signature: sMsg.getSignature(), - }; - }), - }; - // Verify the doubly signed claim with both our public key, and the sender's - const verifiedDoubly = - (await claimsUtils.verifyClaimSignature( - constructedDoublySignedClaim, - keyManager.getRootKeyPairPem().publicKey, - )) && - (await claimsUtils.verifyClaimSignature( - constructedDoublySignedClaim, + }; + // Get the sender's node ID from the claim + const constructedEncodedClaim: ClaimEncoded = { + payload: intermediaryClaimMessage.getPayload(), + signatures: [ + { + protected: intermediarySignature.getProtected(), + signature: intermediarySignature.getSignature(), + }, + ], + }; + const decodedClaim = claimsUtils.decodeClaim(constructedEncodedClaim); + const payloadData = decodedClaim.payload.data; + if (payloadData.type !== 'node') { + throw new claimsErrors.ErrorNodesClaimType(); + } + const { + nodeId, + }: { + nodeId: NodeId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [['nodeId'], () => validationUtils.parseNodeId(value)], + () => value, + ); + }, + { + nodeId: payloadData.node1, + }, + ); + // Verify the claim + const senderPublicKey = await nodeManager.getPublicKey(nodeId); + const verified = await claimsUtils.verifyClaimSignature( + constructedEncodedClaim, senderPublicKey, - )); - if (!verifiedDoubly) { - throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed(); - } - // If verified, then we can safely add to our sigchain - await sigchain.addExistingClaim(constructedDoublySignedClaim); - // Close the stream - await genClaims.next(null); - return; + ); + if (!verified) { + throw new claimsErrors.ErrorSinglySignedClaimVerificationFailed(); + } + // If verified, add your own signature to the received claim + const doublySignedClaim = await claimsUtils.signIntermediaryClaim({ + claim: constructedIntermediaryClaim, + privateKey: keyManager.getRootKeyPairPem().privateKey, + 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, + }, + tran, + ); + // Should never be reached, but just for type safety + if (!doublySignedClaim.payload || !singlySignedClaim.payload) { + throw new claimsErrors.ErrorClaimsUndefinedClaimPayload(); + } + // Write both these claims to a message to send + const crossSignMessage = claimsUtils.createCrossSignMessage({ + singlySignedClaim, + doublySignedClaim, + }); + await genClaims.write(crossSignMessage); + // 4. We expect to receive our singly signed claim we sent to now be a + // doubly signed claim (signed by the other node). + const responseStatus = await genClaims.read(); + if (responseStatus.done) { + throw new claimsErrors.ErrorEmptyStream(); + } + const receivedResponse = responseStatus.value; + const receivedDoublySignedClaimMessage = + receivedResponse.getDoublySignedClaim(); + if (!receivedDoublySignedClaimMessage) { + throw new claimsErrors.ErrorUndefinedDoublySignedClaim(); + } + // Reconstruct the expected object from message + const constructedDoublySignedClaim: ClaimEncoded = { + payload: receivedDoublySignedClaimMessage.getPayload(), + signatures: receivedDoublySignedClaimMessage + .getSignaturesList() + .map((sMsg) => { + return { + protected: sMsg.getProtected(), + signature: sMsg.getSignature(), + }; + }), + }; + // Verify the doubly signed claim with both our public key, and the sender's + const verifiedDoubly = + (await claimsUtils.verifyClaimSignature( + constructedDoublySignedClaim, + keyManager.getRootKeyPairPem().publicKey, + )) && + (await claimsUtils.verifyClaimSignature( + constructedDoublySignedClaim, + senderPublicKey, + )); + if (!verifiedDoubly) { + throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed(); + } + // If verified, then we can safely add to our sigchain + await sigchain.addExistingClaim(constructedDoublySignedClaim, tran); + // Close the stream + await genClaims.next(null); + return; + }); } catch (e) { await genClaims.throw(e); logger.error(e); diff --git a/src/sigchain/Sigchain.ts b/src/sigchain/Sigchain.ts index 0a7f8bb65..25614e490 100644 --- a/src/sigchain/Sigchain.ts +++ b/src/sigchain/Sigchain.ts @@ -1,4 +1,4 @@ -import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; +import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { ChainDataEncoded } from './types'; import type { ClaimData, @@ -17,6 +17,7 @@ import { 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'; @@ -32,6 +33,7 @@ class Sigchain { protected logger: Logger; protected keyManager: KeyManager; protected db: DB; + 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) @@ -125,9 +127,16 @@ class Sigchain { @ready(new sigchainErrors.ErrorSigchainNotRunning()) public async withTransactionF( - f: (tran: DBTransaction) => Promise, + ...params: [...keys: Array, f: (tran: DBTransaction) => Promise] ): Promise { - return withF([this.db.transaction()], ([tran]) => f(tran)); + 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), + ); } /** @@ -171,9 +180,17 @@ class Sigchain { claimData: ClaimData, tran?: DBTransaction, ): Promise<[ClaimId, ClaimEncoded]> { + const claimId = this.generateClaimId(); + const claimIdPath = [...this.sigchainClaimsDbPath, claimId.toBuffer()]; + const sequenceNumberPath = [ + ...this.sigchainMetadataDbPath, + this.sequenceNumberKey, + ]; if (tran == null) { - return this.withTransactionF(async (tran) => - this.addClaim(claimData, tran), + return this.withTransactionF( + claimIdPath, + sequenceNumberPath, + async (tran) => this.addClaim(claimData, tran), ); } const prevSequenceNumber = await this.getSequenceNumber(tran); @@ -184,12 +201,8 @@ class Sigchain { data: claimData, }); // Add the claim to the sigchain database, and update the sequence number - const claimId = this.generateClaimId(); - await tran.put([...this.sigchainClaimsDbPath, claimId.toBuffer()], claim); - await tran.put( - [...this.sigchainMetadataDbPath, this.sequenceNumberKey], - newSequenceNumber, - ); + await tran.put(claimIdPath, claim); + await tran.put(sequenceNumberPath, newSequenceNumber); return [claimId, claim]; } @@ -206,9 +219,17 @@ class Sigchain { 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(async (tran) => - this.addExistingClaim(claim, tran), + return this.withTransactionF( + claimIdPath, + sequenceNumberPath, + async (tran) => this.addExistingClaim(claim, tran), ); } const decodedClaim = claimsUtils.decodeClaim(claim); @@ -221,14 +242,8 @@ class Sigchain { if (decodedClaim.payload.hPrev !== (await this.getHashPrevious(tran))) { throw new sigchainErrors.ErrorSigchainInvalidHash(); } - await tran.put( - [...this.sigchainClaimsDbPath, this.generateClaimId().toBuffer()], - claim, - ); - await tran.put( - [...this.sigchainMetadataDbPath, this.sequenceNumberKey], - expectedSequenceNumber, - ); + await tran.put(claimIdPath, claim); + await tran.put(sequenceNumberPath, expectedSequenceNumber); } /** @@ -240,8 +255,12 @@ class Sigchain { claimData: ClaimData, tran?: DBTransaction, ): Promise { + const sequenceNumberPath = [ + ...this.sigchainMetadataDbPath, + this.sequenceNumberKey, + ]; if (tran == null) { - return this.withTransactionF(async (tran) => + return this.withTransactionF(sequenceNumberPath, async (tran) => this.createIntermediaryClaim(claimData, tran), ); } @@ -314,12 +333,7 @@ class Sigchain { * @returns previous sequence number */ @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async getSequenceNumber(tran?: DBTransaction): Promise { - if (tran == null) { - return this.withTransactionF(async (tran) => - this.getSequenceNumber(tran), - ); - } + protected async getSequenceNumber(tran: DBTransaction): Promise { const sequenceNumber = await tran.get([ ...this.sigchainMetadataDbPath, this.sequenceNumberKey, @@ -336,10 +350,7 @@ class Sigchain { * Helper function to compute the hash of the previous claim. */ @ready(new sigchainErrors.ErrorSigchainNotRunning()) - public async getHashPrevious(tran?: DBTransaction): Promise { - if (tran == null) { - return this.withTransactionF(async (tran) => this.getHashPrevious(tran)); - } + protected async getHashPrevious(tran: DBTransaction): Promise { const prevSequenceNumber = await this.getLatestClaimId(tran); if (prevSequenceNumber == null) { // If no other claims, then null 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/sigchain/Sigchain.test.ts b/tests/sigchain/Sigchain.test.ts index e36a70e10..e53a4c67f 100644 --- a/tests/sigchain/Sigchain.test.ts +++ b/tests/sigchain/Sigchain.test.ts @@ -105,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(); }); @@ -249,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({ @@ -265,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); @@ -283,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); From 480eaa48474ef6a28734c42c7ee9ab29aba7320e Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 17 May 2022 12:51:10 +1000 Subject: [PATCH 29/74] fix: added locking back into notifications Notifications have strict ordering in the DB, therefore locking is required. --- src/notifications/NotificationsManager.ts | 258 ++++++++++++---------- 1 file changed, 138 insertions(+), 120 deletions(-) diff --git a/src/notifications/NotificationsManager.ts b/src/notifications/NotificationsManager.ts index 83eca6f7b..b2780000a 100644 --- a/src/notifications/NotificationsManager.ts +++ b/src/notifications/NotificationsManager.ts @@ -1,4 +1,4 @@ -import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; +import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { NotificationId, Notification, @@ -12,13 +12,13 @@ import type NodeConnectionManager from '../nodes/NodeConnectionManager'; import type { NodeId } from '../nodes/types'; import Logger from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; -import { Lock } from '@matrixai/async-locks'; +import { Lock, LockBox } from '@matrixai/async-locks'; import { CreateDestroyStartStop, ready, } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { utils as idUtils } from '@matrixai/id'; -import * as resources from '@matrixai/resources'; +import { withF } from '@matrixai/resources'; import * as notificationsUtils from './utils'; import * as notificationsErrors from './errors'; import * as notificationsPB from '../proto/js/polykey/v1/notifications/notifications_pb'; @@ -77,7 +77,7 @@ class NotificationsManager { protected nodeManager: NodeManager; protected nodeConnectionManager: NodeConnectionManager; protected messageCap: number; - protected lock: Lock = new Lock(); + protected locks: LockBox = new LockBox(); /** * Top level stores MESSAGE_COUNT_KEY -> number (of messages) @@ -122,25 +122,34 @@ class NotificationsManager { public async start({ fresh = false, }: { fresh?: boolean } = {}): Promise { - await this.db.withTransactionF(async (tran) => { - this.logger.info(`Starting ${this.constructor.name}`); - if (fresh) { - await tran.clear(this.notificationsDbPath); - } + 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 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}`); - }); + // 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() { @@ -156,6 +165,20 @@ class NotificationsManager { this.logger.info(`Destroyed ${this.constructor.name}`); } + @ready(new notificationsErrors.ErrorNotificationsNotRunning()) + 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), + ); + } + /** * Send a notification to another node * The `data` parameter must match one of the NotificationData types outlined in ./types @@ -186,50 +209,45 @@ class NotificationsManager { * Receive a notification */ @ready(new notificationsErrors.ErrorNotificationsNotRunning()) - public async receiveNotification(notification: Notification): Promise { - return await resources.withF( - [this.db.transaction(), this.lock.lock()], - async ([tran]) => { - 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([ - ...this.notificationsDbPath, - MESSAGE_COUNT_KEY, - ]); - if (numMessages === undefined) { - numMessages = 0; - await tran.put([...this.notificationsDbPath, MESSAGE_COUNT_KEY], 0); - } - 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( - [...this.notificationsDbPath, MESSAGE_COUNT_KEY], - newNumMessages, - ); - } - }, + 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), + ); + } + 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); + } + 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); + } } /** @@ -240,39 +258,41 @@ class NotificationsManager { unread = false, number = 'all', order = 'newest', + tran, }: { unread?: boolean; number?: number | 'all'; order?: 'newest' | 'oldest'; + tran?: DBTransaction; } = {}): Promise> { - return await resources.withF( - [this.db.transaction(), this.lock.lock()], - async ([tran]) => { - let notificationIds: Array; - if (unread) { - notificationIds = await this.getNotificationIds('unread', tran); - } else { - notificationIds = await this.getNotificationIds('all', tran); - } + if (tran == null) { + return this.withTransactionF(async (tran) => + this.readNotifications({ unread, number, order, tran }), + ); + } + let notificationIds: Array; + if (unread) { + notificationIds = await this.getNotificationIds('unread', tran); + } else { + notificationIds = await this.getNotificationIds('all', tran); + } - if (order === 'newest') { - notificationIds.reverse(); - } + if (order === 'newest') { + notificationIds.reverse(); + } - if (number === 'all' || number > notificationIds.length) { - number = notificationIds.length; - } - notificationIds = notificationIds.slice(0, number); + if (number === 'all' || number > notificationIds.length) { + number = notificationIds.length; + } + notificationIds = notificationIds.slice(0, number); - const notifications: Array = []; - for (const id of notificationIds) { - const notification = await this.readNotificationById(id, tran); - notifications.push(notification!); - } + const notifications: Array = []; + for (const id of notificationIds) { + const notification = await this.readNotificationById(id, tran); + notifications.push(notification!); + } - return notifications; - }, - ); + return notifications; } /** @@ -282,43 +302,42 @@ class NotificationsManager { @ready(new notificationsErrors.ErrorNotificationsNotRunning()) public async findGestaltInvite( fromNode: NodeId, + tran?: DBTransaction, ): Promise { - return await resources.withF( - [this.db.transaction(), this.lock.lock()], - async ([tran]) => { - const notifications = await this.getNotifications('all', tran); - for (const notification of notifications) { - if ( - notification.data.type === 'GestaltInvite' && - nodesUtils.decodeNodeId(notification.senderId)!.equals(fromNode) - ) { - return notification; - } - } - }, - ); + 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' && + nodesUtils.decodeNodeId(notification.senderId)!.equals(fromNode) + ) { + return notification; + } + } } /** * Removes all notifications */ @ready(new notificationsErrors.ErrorNotificationsNotRunning()) - public async clearNotifications(): Promise { - await resources.withF( - [this.db.transaction(), this.lock.lock()], - async ([tran]) => { - const notificationIds = await this.getNotificationIds('all', tran); - const numMessages = await tran.get([ - ...this.notificationsDbPath, - MESSAGE_COUNT_KEY, - ]); - if (numMessages !== undefined) { - for (const id of notificationIds) { - await this.removeNotification(id, tran); - } - } - }, - ); + 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), + ); + } + 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); + } + } } protected async readNotificationById( @@ -365,7 +384,6 @@ class NotificationsManager { tran: DBTransaction, ): Promise> { const notifications: Array = []; - // This.notificationsMessagesDb.createValueStream() for await (const [, value] of tran.iterator( {}, this.notificationsMessagesDbPath, From 61c551160ee8b3574c761306a9eb2a011d9da960 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 17 May 2022 13:42:02 +1000 Subject: [PATCH 30/74] fix: discovery test fixes --- src/discovery/Discovery.ts | 12 ++++-------- tests/discovery/Discovery.test.ts | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/discovery/Discovery.ts b/src/discovery/Discovery.ts index 42d0fe154..53026b098 100644 --- a/src/discovery/Discovery.ts +++ b/src/discovery/Discovery.ts @@ -13,8 +13,8 @@ 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 Logger from '@matrixai/logger'; @@ -83,11 +83,7 @@ class Discovery { protected gestaltGraph: GestaltGraph; protected identitiesManager: IdentitiesManager; protected nodeManager: NodeManager; - protected discoveryDbDomain: string = this.constructor.name; - protected discoveryQueueDbDomain: Array = [ - this.discoveryDbDomain, - 'queue', - ]; + protected discoveryDbPath: LevelPath = [this.constructor.name]; protected discoveryQueueDbPath: LevelPath = [this.constructor.name, 'queue']; protected discoveryQueueIdGenerator: DiscoveryQueueIdGenerator; @@ -457,7 +453,7 @@ class Discovery { } const discoveryQueueId = this.discoveryQueueIdGenerator(); await tran.put( - [...this.discoveryQueueDbDomain, idUtils.toBuffer(discoveryQueueId)], + [...this.discoveryQueueDbPath, idUtils.toBuffer(discoveryQueueId)], gestaltKey, ); }, diff --git a/tests/discovery/Discovery.test.ts b/tests/discovery/Discovery.test.ts index abfcab85d..c11c8d000 100644 --- a/tests/discovery/Discovery.test.ts +++ b/tests/discovery/Discovery.test.ts @@ -6,14 +6,16 @@ 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 * as nodesUtils from '@/nodes/utils'; import * as claimsUtils from '@/claims/utils'; From dd126c0346605631431a7a7ac2aaeb2cf4c0a6f6 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 17 May 2022 13:50:21 +1000 Subject: [PATCH 31/74] fix: fix for `NodeConnection.test.ts` not running --- tests/nodes/NodeConnection.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/nodes/NodeConnection.test.ts b/tests/nodes/NodeConnection.test.ts index 52d1ce674..fcc37d701 100644 --- a/tests/nodes/NodeConnection.test.ts +++ b/tests/nodes/NodeConnection.test.ts @@ -267,6 +267,7 @@ describe(`${NodeConnection.name} test`, () => { }); await serverGestaltGraph.setNode(node); const agentService = createAgentService({ + db: serverDb, keyManager: serverKeyManager, vaultManager: serverVaultManager, nodeConnectionManager: dummyNodeConnectionManager, From 70d368e2ccb0c28335a5f8a77d1528992f74c85f Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 17 May 2022 14:37:21 +1000 Subject: [PATCH 32/74] refactor: replacing `Mutex` with `Lock` for Proxy --- src/network/Proxy.ts | 285 ++++++++++++++++++------------------ tests/network/Proxy.test.ts | 14 +- 2 files changed, 150 insertions(+), 149 deletions(-) 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/tests/network/Proxy.test.ts b/tests/network/Proxy.test.ts index 4393c69b9..afd93c3b4 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(); From a17cb0bb1f9b205e4d494e5ea943f6139219c90e Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 17 May 2022 15:46:13 +1000 Subject: [PATCH 33/74] fix: fixing vaultManager tests There are still some tests failing due to cloning and pulling. Seems like a problem with the HTTP API for cloning. --- tests/vaults/VaultManager.test.ts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/tests/vaults/VaultManager.test.ts b/tests/vaults/VaultManager.test.ts index 61796e807..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') @@ -736,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(); @@ -824,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 { @@ -1519,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'); From d32cb3bbc5cca9eef54dd1ed2ea7e5515a1a37ae Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 17 May 2022 17:29:23 +1000 Subject: [PATCH 34/74] test: fixing client tests --- tests/client/rpcVaults.test.ts | 7 +- tests/client/service/agentLockAll.test.ts | 1 + .../gestaltsGestaltTrustByIdentity.test.ts | 67 ++---- .../service/identitiesAuthenticate.test.ts | 6 +- tests/client/service/identitiesClaim.test.ts | 16 +- .../identitiesInfoConnectedGet.test.ts | 6 +- tests/client/service/keysKeyPairRenew.test.ts | 4 +- tests/client/service/keysKeyPairReset.test.ts | 4 +- tests/client/service/nodesAdd.test.ts | 16 +- tests/client/service/nodesClaim.test.ts | 6 +- tests/client/service/nodesFind.test.ts | 6 +- tests/client/service/nodesPing.test.ts | 6 +- tests/utils.ts | 215 +++++++++--------- 13 files changed, 175 insertions(+), 185 deletions(-) diff --git a/tests/client/rpcVaults.test.ts b/tests/client/rpcVaults.test.ts index 96f3db089..8645e989f 100644 --- a/tests/client/rpcVaults.test.ts +++ b/tests/client/rpcVaults.test.ts @@ -19,6 +19,7 @@ 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'), @@ -247,7 +248,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 +257,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 4ae0d6665..9fd74aab4 100644 --- a/tests/client/service/agentLockAll.test.ts +++ b/tests/client/service/agentLockAll.test.ts @@ -76,6 +76,7 @@ describe('agentLockall', () => { authenticate, sessionManager, logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts b/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts index 74ecff0e3..ba706add1 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( @@ -300,34 +299,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), @@ -351,20 +331,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( @@ -415,35 +397,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/identitiesAuthenticate.test.ts b/tests/client/service/identitiesAuthenticate.test.ts index 73bce737e..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, [ @@ -125,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/identitiesClaim.test.ts b/tests/client/service/identitiesClaim.test.ts index 6259afaea..70185582a 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, [ @@ -208,27 +209,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 300567584..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, [ @@ -729,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/keysKeyPairRenew.test.ts b/tests/client/service/keysKeyPairRenew.test.ts index 550f793dd..8a792254b 100644 --- a/tests/client/service/keysKeyPairRenew.test.ts +++ b/tests/client/service/keysKeyPairRenew.test.ts @@ -111,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); @@ -134,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 754d80075..8c41064b1 100644 --- a/tests/client/service/keysKeyPairReset.test.ts +++ b/tests/client/service/keysKeyPairReset.test.ts @@ -111,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); @@ -134,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/nodesAdd.test.ts b/tests/client/service/nodesAdd.test.ts index 168e64a34..aaff85bc3 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, [ @@ -175,29 +176,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 2686ce3ed..bcecd0741 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, [ @@ -229,11 +230,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 0297bccbd..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, [ @@ -159,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 43dddcba1..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, [ @@ -174,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/utils.ts b/tests/utils.ts index f6f76c538..38bd48fcd 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -1,20 +1,20 @@ -// Import type { StatusLive } from '@/status/types'; +import type { StatusLive } from '@/status/types'; import type { NodeId } from '@/nodes/types'; -// Import type { Host } from '@/network/types'; +import type { Host } from '@/network/types'; import path from 'path'; import fs from 'fs'; import lock from 'fd-lock'; -// Import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; -// Import PolykeyAgent from '@/PolykeyAgent'; -// import Status from '@/status/Status'; -// import GRPCClientClient from '@/client/GRPCClientClient'; -// import * as clientUtils from '@/client/utils'; +import PolykeyAgent from '@/PolykeyAgent'; +import Status from '@/status/Status'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import * as clientUtils from '@/client/utils'; import * as keysUtils from '@/keys/utils'; -// Import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import { sleep } from '@/utils'; import * as errors from '@/errors'; -// Import config from '@/config'; +import config from '@/config'; /** * Setup the global keypair @@ -84,101 +84,101 @@ async function setupGlobalKeypair() { * * Ensure client-side side-effects are removed at the end of each test * * Ensure server-side side-effects are removed at the end of each test */ -// async function setupGlobalAgent( -// logger: Logger = new Logger(setupGlobalAgent.name, LogLevel.WARN, [ -// new StreamHandler(), -// ]), -// ) { -// const globalAgentPassword = 'password'; -// const globalAgentDir = path.join(globalThis.dataDir, 'agent'); -// // The references directory will act like our reference count -// await fs.promises.mkdir(path.join(globalAgentDir, 'references'), { -// recursive: true, -// }); -// const pid = process.pid.toString(); -// // Plus 1 to the reference count -// await fs.promises.writeFile(path.join(globalAgentDir, 'references', pid), ''); -// const globalAgentLock = await fs.promises.open( -// path.join(globalThis.dataDir, 'agent.lock'), -// fs.constants.O_WRONLY | fs.constants.O_CREAT, -// ); -// while (!lock(globalAgentLock.fd)) { -// await sleep(1000); -// } -// const status = new Status({ -// statusPath: path.join(globalAgentDir, config.defaults.statusBase), -// statusLockPath: path.join(globalAgentDir, config.defaults.statusLockBase), -// fs, -// }); -// let statusInfo = await status.readStatus(); -// if (statusInfo == null || statusInfo.status === 'DEAD') { -// await PolykeyAgent.createPolykeyAgent({ -// password: globalAgentPassword, -// nodePath: globalAgentDir, -// networkConfig: { -// proxyHost: '127.0.0.1' as Host, -// forwardHost: '127.0.0.1' as Host, -// agentHost: '127.0.0.1' as Host, -// clientHost: '127.0.0.1' as Host, -// }, -// keysConfig: { -// rootKeyPairBits: 2048, -// }, -// seedNodes: {}, // Explicitly no seed nodes on startup -// logger, -// }); -// statusInfo = await status.readStatus(); -// } -// return { -// globalAgentDir, -// globalAgentPassword, -// globalAgentStatus: statusInfo as StatusLive, -// globalAgentClose: async () => { -// // Closing the global agent cannot be done in the globalTeardown -// // This is due to a sequence of reasons: -// // 1. The global agent is not started as a separate process -// // 2. Because we need to be able to mock dependencies -// // 3. This means it is part of a jest worker process -// // 4. Which will block termination of the jest worker process -// // 5. Therefore globalTeardown will never get to execute -// // 6. The global agent is not part of globalSetup -// // 7. Because not all tests need the global agent -// // 8. Therefore setupGlobalAgent is lazy and executed by jest worker processes -// try { -// await fs.promises.rm(path.join(globalAgentDir, 'references', pid)); -// // If the references directory is not empty -// // there are other processes still using the global agent -// try { -// await fs.promises.rmdir(path.join(globalAgentDir, 'references')); -// } catch (e) { -// if (e.code === 'ENOTEMPTY') { -// return; -// } -// throw e; -// } -// // Stopping may occur in a different jest worker process -// // therefore we cannot rely on pkAgent, but instead use GRPC -// const statusInfo = (await status.readStatus()) as StatusLive; -// const grpcClient = await GRPCClientClient.createGRPCClientClient({ -// nodeId: statusInfo.data.nodeId, -// host: statusInfo.data.clientHost, -// port: statusInfo.data.clientPort, -// tlsConfig: { keyPrivatePem: undefined, certChainPem: undefined }, -// logger, -// }); -// const emptyMessage = new utilsPB.EmptyMessage(); -// const meta = clientUtils.encodeAuthFromPassword(globalAgentPassword); -// // This is asynchronous -// await grpcClient.agentStop(emptyMessage, meta); -// await grpcClient.destroy(); -// await status.waitFor('DEAD'); -// } finally { -// lock.unlock(globalAgentLock.fd); -// await globalAgentLock.close(); -// } -// }, -// }; -// } +async function setupGlobalAgent( + logger: Logger = new Logger(setupGlobalAgent.name, LogLevel.WARN, [ + new StreamHandler(), + ]), +) { + const globalAgentPassword = 'password'; + const globalAgentDir = path.join(globalThis.dataDir, 'agent'); + // The references directory will act like our reference count + await fs.promises.mkdir(path.join(globalAgentDir, 'references'), { + recursive: true, + }); + const pid = process.pid.toString(); + // Plus 1 to the reference count + await fs.promises.writeFile(path.join(globalAgentDir, 'references', pid), ''); + const globalAgentLock = await fs.promises.open( + path.join(globalThis.dataDir, 'agent.lock'), + fs.constants.O_WRONLY | fs.constants.O_CREAT, + ); + while (!lock(globalAgentLock.fd)) { + await sleep(1000); + } + const status = new Status({ + statusPath: path.join(globalAgentDir, config.defaults.statusBase), + statusLockPath: path.join(globalAgentDir, config.defaults.statusLockBase), + fs, + }); + let statusInfo = await status.readStatus(); + if (statusInfo == null || statusInfo.status === 'DEAD') { + await PolykeyAgent.createPolykeyAgent({ + password: globalAgentPassword, + nodePath: globalAgentDir, + networkConfig: { + proxyHost: '127.0.0.1' as Host, + forwardHost: '127.0.0.1' as Host, + agentHost: '127.0.0.1' as Host, + clientHost: '127.0.0.1' as Host, + }, + keysConfig: { + rootKeyPairBits: 2048, + }, + seedNodes: {}, // Explicitly no seed nodes on startup + logger, + }); + statusInfo = await status.readStatus(); + } + return { + globalAgentDir, + globalAgentPassword, + globalAgentStatus: statusInfo as StatusLive, + globalAgentClose: async () => { + // Closing the global agent cannot be done in the globalTeardown + // This is due to a sequence of reasons: + // 1. The global agent is not started as a separate process + // 2. Because we need to be able to mock dependencies + // 3. This means it is part of a jest worker process + // 4. Which will block termination of the jest worker process + // 5. Therefore globalTeardown will never get to execute + // 6. The global agent is not part of globalSetup + // 7. Because not all tests need the global agent + // 8. Therefore setupGlobalAgent is lazy and executed by jest worker processes + try { + await fs.promises.rm(path.join(globalAgentDir, 'references', pid)); + // If the references directory is not empty + // there are other processes still using the global agent + try { + await fs.promises.rmdir(path.join(globalAgentDir, 'references')); + } catch (e) { + if (e.code === 'ENOTEMPTY') { + return; + } + throw e; + } + // Stopping may occur in a different jest worker process + // therefore we cannot rely on pkAgent, but instead use GRPC + const statusInfo = (await status.readStatus()) as StatusLive; + const grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: statusInfo.data.nodeId, + host: statusInfo.data.clientHost, + port: statusInfo.data.clientPort, + tlsConfig: { keyPrivatePem: undefined, certChainPem: undefined }, + logger, + }); + const emptyMessage = new utilsPB.EmptyMessage(); + const meta = clientUtils.encodeAuthFromPassword(globalAgentPassword); + // This is asynchronous + await grpcClient.agentStop(emptyMessage, meta); + await grpcClient.destroy(); + await status.waitFor('DEAD'); + } finally { + lock.unlock(globalAgentLock.fd); + await globalAgentLock.close(); + } + }, + }; +} function generateRandomNodeId(): NodeId { const random = keysUtils.getRandomBytesSync(16).toString('hex'); @@ -197,4 +197,9 @@ const expectRemoteError = async ( } }; -export { setupGlobalKeypair, generateRandomNodeId, expectRemoteError }; +export { + setupGlobalKeypair, + generateRandomNodeId, + expectRemoteError, + setupGlobalAgent, +}; From 25ef70d7ebbd6bca205a28abe1c1d8c970b3612a Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 17 May 2022 18:28:58 +1000 Subject: [PATCH 35/74] test: fixes for agent tests --- tests/agent/GRPCClientAgent.test.ts | 1 + tests/agent/service/nodesCrossSignClaim.test.ts | 8 ++------ tests/agent/service/notificationsSend.test.ts | 14 ++++++++------ tests/agent/utils.ts | 11 +++++++---- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/tests/agent/GRPCClientAgent.test.ts b/tests/agent/GRPCClientAgent.test.ts index 78808e361..2a9392e74 100644 --- a/tests/agent/GRPCClientAgent.test.ts +++ b/tests/agent/GRPCClientAgent.test.ts @@ -156,6 +156,7 @@ describe(GRPCClientAgent.name, () => { acl, gestaltGraph, proxy, + db, }); 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 5b3f6c53e..bc676db86 100644 --- a/tests/agent/service/nodesCrossSignClaim.test.ts +++ b/tests/agent/service/nodesCrossSignClaim.test.ts @@ -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,7 @@ describe('nodesCrossSignClaim', () => { keyManager: pkAgent.keyManager, nodeManager: pkAgent.nodeManager, sigchain: pkAgent.sigchain, + db: pkAgent.db, logger, }), }; @@ -137,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; @@ -176,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(); @@ -208,7 +206,6 @@ describe('nodesCrossSignClaim', () => { 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(); @@ -228,7 +225,6 @@ describe('nodesCrossSignClaim', () => { 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 3732b407e..5d51289e0 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, [ @@ -222,9 +223,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); @@ -249,9 +251,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); @@ -274,9 +277,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..296707684 100644 --- a/tests/agent/utils.ts +++ b/tests/agent/utils.ts @@ -3,20 +3,21 @@ 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 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 +32,7 @@ async function openTestAgentServer({ acl, gestaltGraph, proxy, + db, }: { keyManager: KeyManager; vaultManager: VaultManager; @@ -42,6 +44,7 @@ async function openTestAgentServer({ acl: ACL; gestaltGraph: GestaltGraph; proxy: Proxy; + db: DB; }) { const agentService: IAgentServiceServer = createAgentService({ keyManager, @@ -54,6 +57,7 @@ async function openTestAgentServer({ acl, gestaltGraph, proxy, + db, }); const server = new grpc.Server(); @@ -80,7 +84,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 +93,6 @@ async function openTestAgentClient( proxyConfig, timeout: 30000, }); - return agentClient; } async function closeTestAgentClient(client: GRPCClientAgent) { From 30db49cf7b84c70518dea919c4bcfb12f01274b5 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 17 May 2022 18:43:08 +1000 Subject: [PATCH 36/74] test: fixes for grpc tests --- tests/grpc/GRPCClient.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/grpc/GRPCClient.test.ts b/tests/grpc/GRPCClient.test.ts index de8618005..31028187e 100644 --- a/tests/grpc/GRPCClient.test.ts +++ b/tests/grpc/GRPCClient.test.ts @@ -18,6 +18,7 @@ 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, [ @@ -173,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( From 8517292bd17a1540a804c0e4c7a1feae4f636fbd Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Wed, 18 May 2022 16:08:31 +1000 Subject: [PATCH 37/74] feat: error serialisation/deserialisation + metadata --- src/ErrorPolykey.ts | 83 +++----- src/agent/GRPCClientAgent.ts | 30 +++ src/agent/service/nodesChainDataGet.ts | 4 +- .../service/nodesClosestLocalNodesGet.ts | 9 +- .../service/nodesHolePunchMessageSend.ts | 8 +- src/agent/service/notificationsSend.ts | 6 +- src/client/GRPCClientClient.ts | 192 ++++++++++++++++++ .../service/gestaltsActionsGetByNode.ts | 7 +- .../service/gestaltsActionsSetByIdentity.ts | 7 +- .../service/gestaltsActionsSetByNode.ts | 7 +- .../service/gestaltsActionsUnsetByIdentity.ts | 7 +- .../service/gestaltsActionsUnsetByNode.ts | 7 +- .../service/gestaltsDiscoveryByIdentity.ts | 2 +- src/client/service/gestaltsDiscoveryByNode.ts | 2 +- .../service/gestaltsGestaltGetByIdentity.ts | 7 +- .../service/gestaltsGestaltGetByNode.ts | 7 +- src/client/service/gestaltsGestaltList.ts | 4 +- .../service/gestaltsGestaltTrustByIdentity.ts | 4 +- .../service/gestaltsGestaltTrustByNode.ts | 4 +- src/client/service/identitiesAuthenticate.ts | 9 +- .../service/identitiesAuthenticatedGet.ts | 2 +- src/client/service/identitiesClaim.ts | 15 +- .../service/identitiesInfoConnectedGet.ts | 2 +- src/client/service/identitiesInfoGet.ts | 2 +- src/client/service/identitiesProvidersList.ts | 4 +- src/client/service/identitiesTokenDelete.ts | 7 +- src/client/service/identitiesTokenGet.ts | 7 +- src/client/service/identitiesTokenPut.ts | 7 +- src/client/service/index.ts | 4 +- src/client/service/keysCertsChainGet.ts | 4 +- src/client/service/keysCertsGet.ts | 4 +- src/client/service/keysDecrypt.ts | 4 +- src/client/service/keysEncrypt.ts | 4 +- src/client/service/keysKeyPairRenew.ts | 4 +- src/client/service/keysKeyPairReset.ts | 4 +- src/client/service/keysKeyPairRoot.ts | 4 +- src/client/service/keysPasswordChange.ts | 4 +- src/client/service/keysSign.ts | 4 +- src/client/service/keysVerify.ts | 4 +- src/client/service/nodesAdd.ts | 7 +- src/client/service/nodesClaim.ts | 9 +- src/client/service/nodesFind.ts | 9 +- src/client/service/nodesPing.ts | 7 +- src/client/service/notificationsClear.ts | 4 +- src/client/service/notificationsRead.ts | 4 +- src/client/service/notificationsSend.ts | 9 +- src/client/service/vaultsPermissionGet.ts | 2 +- src/client/utils/utils.ts | 4 +- src/grpc/GRPCClient.ts | 8 + src/grpc/utils/utils.ts | 165 +++++++++++---- tests/client/service/agentLockAll.test.ts | 1 + 51 files changed, 519 insertions(+), 206 deletions(-) diff --git a/src/ErrorPolykey.ts b/src/ErrorPolykey.ts index deba43ef2..4ee452242 100644 --- a/src/ErrorPolykey.ts +++ b/src/ErrorPolykey.ts @@ -1,61 +1,42 @@ -import type { POJO } from './types'; +import type { Class } from '@matrixai/errors'; import { AbstractError } from '@matrixai/errors'; import sysexits from './utils/sysexits'; class ErrorPolykey extends AbstractError { static description: string = 'Polykey error'; exitCode: number = sysexits.GENERAL; - public toJSON( - _key: string = '', - options: { - description?: boolean; - message?: boolean; - exitCode?: boolean; - timestamp?: boolean; - data?: boolean; - cause?: boolean; - stack?: boolean; - } = {}, - ): { - type: string; - data: { - description?: string; - message?: string; - exitCode?: number; - timestamp?: Date; - data?: POJO; - cause?: T; - stack?: string; - }; - } { - options.description ??= true; - options.message ??= true; - options.exitCode ??= true; - options.timestamp ??= true; - options.data ??= true; - options.cause ??= true; - options.stack ??= true; - const data: POJO = {}; - if (options.description) data.description = this.description; - if (options.message) data.message = this.message; - if (options.exitCode) data.exitCode = this.exitCode; - if (options.timestamp) data.timestamp = this.timestamp; - if (options.data) data.data = this.data; - if (options.cause) { - // Propagate the options down the exception chain - // but only if the cause is another AbstractError - if (this.cause instanceof ErrorPolykey) { - data.cause = this.cause.toJSON('cause', options); - } else { - // Use `replacer` to further encode this object - data.cause = this.cause; - } + + 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 !== 'string' || + !('cause' in json.data) || + ('stack' in json.data && typeof json.data.stack !== 'string') + ) { + throw new TypeError(`Cannot decode JSON to ${this.name}`); } - if (options.stack) data.stack = this.stack; - return { - type: this.name, - data, - }; + 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/agent/GRPCClientAgent.ts b/src/agent/GRPCClientAgent.ts index 4190f66b6..dd68e2db5 100644 --- a/src/agent/GRPCClientAgent.ts +++ b/src/agent/GRPCClientAgent.ts @@ -79,6 +79,9 @@ class GRPCClientAgent extends GRPCClient { public echo(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.echo, )(...args); } @@ -92,6 +95,9 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsGitInfoGet, )(...args); } @@ -106,6 +112,9 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyDuplexStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsGitPackGet, )(...args); } @@ -119,6 +128,9 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsScan, )(...args); } @@ -127,6 +139,9 @@ class GRPCClientAgent extends GRPCClient { public nodesClosestLocalNodesGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesClosestLocalNodesGet, )(...args); } @@ -135,6 +150,9 @@ class GRPCClientAgent extends GRPCClient { public nodesClaimsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesClaimsGet, )(...args); } @@ -143,6 +161,9 @@ class GRPCClientAgent extends GRPCClient { public nodesChainDataGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesChainDataGet, )(...args); } @@ -151,6 +172,9 @@ class GRPCClientAgent extends GRPCClient { public nodesHolePunchMessageSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesHolePunchMessageSend, )(...args); } @@ -159,6 +183,9 @@ class GRPCClientAgent extends GRPCClient { public notificationsSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.notificationsSend, )(...args); } @@ -176,6 +203,9 @@ class GRPCClientAgent extends GRPCClient { nodesPB.CrossSign >( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesCrossSignClaim, )(...args); } diff --git a/src/agent/service/nodesChainDataGet.ts b/src/agent/service/nodesChainDataGet.ts index 4301dff01..f2970228f 100644 --- a/src/agent/service/nodesChainDataGet.ts +++ b/src/agent/service/nodesChainDataGet.ts @@ -1,9 +1,9 @@ import type * as grpc from '@grpc/grpc-js'; -import type { Sigchain } from '../../sigchain'; +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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; /** diff --git a/src/agent/service/nodesClosestLocalNodesGet.ts b/src/agent/service/nodesClosestLocalNodesGet.ts index dc709195b..ee031f478 100644 --- a/src/agent/service/nodesClosestLocalNodesGet.ts +++ b/src/agent/service/nodesClosestLocalNodesGet.ts @@ -1,10 +1,11 @@ import type * as grpc from '@grpc/grpc-js'; -import type { NodeConnectionManager } from '../../nodes'; +import type NodeConnectionManager from '../../nodes/NodeConnectionManager'; import type { NodeId } from '../../nodes/types'; import type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; -import { utils as nodesUtils } from '../../nodes'; -import { validateSync, utils as validationUtils } from '../../validation'; +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'; diff --git a/src/agent/service/nodesHolePunchMessageSend.ts b/src/agent/service/nodesHolePunchMessageSend.ts index 438af3775..592d0f482 100644 --- a/src/agent/service/nodesHolePunchMessageSend.ts +++ b/src/agent/service/nodesHolePunchMessageSend.ts @@ -1,12 +1,14 @@ import type * as grpc from '@grpc/grpc-js'; -import type { NodeManager, NodeConnectionManager } from '../../nodes'; +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'; diff --git a/src/agent/service/notificationsSend.ts b/src/agent/service/notificationsSend.ts index f11a18c95..6baef6f9f 100644 --- a/src/agent/service/notificationsSend.ts +++ b/src/agent/service/notificationsSend.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; -import { utils as notificationsUtils } from '../../notifications'; +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({ diff --git a/src/client/GRPCClientClient.ts b/src/client/GRPCClientClient.ts index 3b07305ea..87ff45b6c 100644 --- a/src/client/GRPCClientClient.ts +++ b/src/client/GRPCClientClient.ts @@ -91,6 +91,9 @@ class GRPCClientClient extends GRPCClient { public agentStatus(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.agentStatus, )(...args); } @@ -99,6 +102,9 @@ class GRPCClientClient extends GRPCClient { public agentStop(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.agentStop, )(...args); } @@ -107,6 +113,9 @@ class GRPCClientClient extends GRPCClient { public agentUnlock(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.agentUnlock, )(...args); } @@ -115,6 +124,9 @@ class GRPCClientClient extends GRPCClient { public agentLockAll(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.agentLockAll, )(...args); } @@ -128,6 +140,9 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsList, )(...args); } @@ -136,6 +151,9 @@ class GRPCClientClient extends GRPCClient { public vaultsCreate(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsCreate, )(...args); } @@ -144,6 +162,9 @@ class GRPCClientClient extends GRPCClient { public vaultsRename(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsRename, )(...args); } @@ -152,6 +173,9 @@ class GRPCClientClient extends GRPCClient { public vaultsDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsDelete, )(...args); } @@ -160,6 +184,9 @@ class GRPCClientClient extends GRPCClient { public vaultsClone(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsClone, )(...args); } @@ -168,6 +195,9 @@ class GRPCClientClient extends GRPCClient { public vaultsPull(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsPull, )(...args); } @@ -181,6 +211,9 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsScan, )(...args); } @@ -189,6 +222,9 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsPermissionGet, )(...args); } @@ -197,6 +233,9 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionSet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsPermissionSet, )(...args); } @@ -205,6 +244,9 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionUnset(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsPermissionUnset, )(...args); } @@ -218,6 +260,9 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsList, )(...args); } @@ -226,6 +271,9 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsMkdir(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsMkdir, )(...args); } @@ -234,6 +282,9 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsDelete, )(...args); } @@ -242,6 +293,9 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsEdit(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsEdit, )(...args); } @@ -250,6 +304,9 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsGet, )(...args); } @@ -258,6 +315,9 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsStat(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsStat, )(...args); } @@ -266,6 +326,9 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsRename(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsRename, )(...args); } @@ -274,6 +337,9 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsNew(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsNew, )(...args); } @@ -282,6 +348,9 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsNewDir(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsSecretsNewDir, )(...args); } @@ -290,6 +359,9 @@ class GRPCClientClient extends GRPCClient { public vaultsVersion(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsVersion, )(...args); } @@ -303,6 +375,9 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.vaultsLog, )(...args); } @@ -311,6 +386,9 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairRoot(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysKeyPairRoot, )(...args); } @@ -319,6 +397,9 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairReset(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysKeyPairReset, )(...args); } @@ -327,6 +408,9 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairRenew(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysKeyPairRenew, )(...args); } @@ -335,6 +419,9 @@ class GRPCClientClient extends GRPCClient { public keysEncrypt(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysEncrypt, )(...args); } @@ -343,6 +430,9 @@ class GRPCClientClient extends GRPCClient { public keysDecrypt(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysDecrypt, )(...args); } @@ -351,6 +441,9 @@ class GRPCClientClient extends GRPCClient { public keysSign(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysSign, )(...args); } @@ -359,6 +452,9 @@ class GRPCClientClient extends GRPCClient { public keysVerify(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysVerify, )(...args); } @@ -367,6 +463,9 @@ class GRPCClientClient extends GRPCClient { public keysPasswordChange(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysPasswordChange, )(...args); } @@ -375,6 +474,9 @@ class GRPCClientClient extends GRPCClient { public keysCertsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysCertsGet, )(...args); } @@ -388,6 +490,9 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.keysCertsChainGet, )(...args); } @@ -401,6 +506,9 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsGestaltList, )(...args); } @@ -409,6 +517,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltGetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsGestaltGetByIdentity, )(...args); } @@ -417,6 +528,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltGetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsGestaltGetByNode, )(...args); } @@ -425,6 +539,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsDiscoveryByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsDiscoveryByNode, )(...args); } @@ -433,6 +550,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsDiscoveryByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsDiscoveryByIdentity, )(...args); } @@ -441,6 +561,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsGetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsActionsGetByNode, )(...args); } @@ -449,6 +572,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsGetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsActionsGetByIdentity, )(...args); } @@ -457,6 +583,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsSetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsActionsSetByNode, )(...args); } @@ -465,6 +594,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsSetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsActionsSetByIdentity, )(...args); } @@ -473,6 +605,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsUnsetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsActionsUnsetByNode, )(...args); } @@ -481,6 +616,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsUnsetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsActionsUnsetByIdentity, )(...args); } @@ -489,6 +627,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltTrustByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsGestaltTrustByNode, )(...args); } @@ -497,6 +638,9 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltTrustByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.gestaltsGestaltTrustByIdentity, )(...args); } @@ -505,6 +649,9 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenPut(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesTokenPut, )(...args); } @@ -513,6 +660,9 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesTokenGet, )(...args); } @@ -521,6 +671,9 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesTokenDelete, )(...args); } @@ -529,6 +682,9 @@ class GRPCClientClient extends GRPCClient { public identitiesProvidersList(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesProvidersList, )(...args); } @@ -537,6 +693,9 @@ class GRPCClientClient extends GRPCClient { public nodesAdd(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesAdd, )(...args); } @@ -545,6 +704,9 @@ class GRPCClientClient extends GRPCClient { public nodesPing(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesPing, )(...args); } @@ -553,6 +715,9 @@ class GRPCClientClient extends GRPCClient { public nodesClaim(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesClaim, )(...args); } @@ -561,6 +726,9 @@ class GRPCClientClient extends GRPCClient { public nodesFind(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.nodesFind, )(...args); } @@ -569,6 +737,9 @@ class GRPCClientClient extends GRPCClient { public identitiesAuthenticate(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesAuthenticate, )(...args); } @@ -577,6 +748,9 @@ class GRPCClientClient extends GRPCClient { public identitiesInfoConnectedGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesInfoConnectedGet, )(...args); } @@ -585,6 +759,9 @@ class GRPCClientClient extends GRPCClient { public identitiesInfoGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesInfoGet, )(...args); } @@ -593,6 +770,9 @@ class GRPCClientClient extends GRPCClient { public identitiesClaim(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesClaim, )(...args); } @@ -601,6 +781,9 @@ class GRPCClientClient extends GRPCClient { public identitiesAuthenticatedGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + this.nodeId, + this.host, + this.port, this.client.identitiesAuthenticatedGet, )(...args); } @@ -609,6 +792,9 @@ class GRPCClientClient extends GRPCClient { public notificationsSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.notificationsSend, )(...args); } @@ -617,6 +803,9 @@ class GRPCClientClient extends GRPCClient { public notificationsRead(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.notificationsRead, )(...args); } @@ -625,6 +814,9 @@ class GRPCClientClient extends GRPCClient { public notificationsClear(...args) { return grpcUtils.promisifyUnaryCall( this.client, + this.nodeId, + this.host, + this.port, this.client.notificationsClear, )(...args); } diff --git a/src/client/service/gestaltsActionsGetByNode.ts b/src/client/service/gestaltsActionsGetByNode.ts index 77b6c54fd..162b6be9f 100644 --- a/src/client/service/gestaltsActionsGetByNode.ts +++ b/src/client/service/gestaltsActionsGetByNode.ts @@ -1,11 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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 permissionsPB from '../../proto/js/polykey/v1/permissions/permissions_pb'; diff --git a/src/client/service/gestaltsActionsSetByIdentity.ts b/src/client/service/gestaltsActionsSetByIdentity.ts index 34140fec9..318ca90b6 100644 --- a/src/client/service/gestaltsActionsSetByIdentity.ts +++ b/src/client/service/gestaltsActionsSetByIdentity.ts @@ -1,12 +1,13 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/gestaltsActionsSetByNode.ts b/src/client/service/gestaltsActionsSetByNode.ts index 0c801c350..cd035f0cf 100644 --- a/src/client/service/gestaltsActionsSetByNode.ts +++ b/src/client/service/gestaltsActionsSetByNode.ts @@ -1,12 +1,13 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/gestaltsActionsUnsetByIdentity.ts b/src/client/service/gestaltsActionsUnsetByIdentity.ts index 9ab5ac61e..8cbd2596a 100644 --- a/src/client/service/gestaltsActionsUnsetByIdentity.ts +++ b/src/client/service/gestaltsActionsUnsetByIdentity.ts @@ -1,12 +1,13 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/gestaltsActionsUnsetByNode.ts b/src/client/service/gestaltsActionsUnsetByNode.ts index 795f9c4fc..958a18060 100644 --- a/src/client/service/gestaltsActionsUnsetByNode.ts +++ b/src/client/service/gestaltsActionsUnsetByNode.ts @@ -1,12 +1,13 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/gestaltsDiscoveryByIdentity.ts b/src/client/service/gestaltsDiscoveryByIdentity.ts index c8e515ab7..9834d4e7c 100644 --- a/src/client/service/gestaltsDiscoveryByIdentity.ts +++ b/src/client/service/gestaltsDiscoveryByIdentity.ts @@ -1,6 +1,6 @@ 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'; diff --git a/src/client/service/gestaltsDiscoveryByNode.ts b/src/client/service/gestaltsDiscoveryByNode.ts index 26e575c51..ed8ab18e6 100644 --- a/src/client/service/gestaltsDiscoveryByNode.ts +++ b/src/client/service/gestaltsDiscoveryByNode.ts @@ -1,6 +1,6 @@ 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'; diff --git a/src/client/service/gestaltsGestaltGetByIdentity.ts b/src/client/service/gestaltsGestaltGetByIdentity.ts index 5f2257a82..c303995ee 100644 --- a/src/client/service/gestaltsGestaltGetByIdentity.ts +++ b/src/client/service/gestaltsGestaltGetByIdentity.ts @@ -1,11 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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 gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; diff --git a/src/client/service/gestaltsGestaltGetByNode.ts b/src/client/service/gestaltsGestaltGetByNode.ts index a0ea6f03c..4cb9cf96d 100644 --- a/src/client/service/gestaltsGestaltGetByNode.ts +++ b/src/client/service/gestaltsGestaltGetByNode.ts @@ -1,11 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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 gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; diff --git a/src/client/service/gestaltsGestaltList.ts b/src/client/service/gestaltsGestaltList.ts index 305cd3b7d..690988c20 100644 --- a/src/client/service/gestaltsGestaltList.ts +++ b/src/client/service/gestaltsGestaltList.ts @@ -1,10 +1,10 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; function gestaltsGestaltList({ diff --git a/src/client/service/gestaltsGestaltTrustByIdentity.ts b/src/client/service/gestaltsGestaltTrustByIdentity.ts index df7b60dc4..a5359bc82 100644 --- a/src/client/service/gestaltsGestaltTrustByIdentity.ts +++ b/src/client/service/gestaltsGestaltTrustByIdentity.ts @@ -1,8 +1,8 @@ import type * as grpc from '@grpc/grpc-js'; 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'; diff --git a/src/client/service/gestaltsGestaltTrustByNode.ts b/src/client/service/gestaltsGestaltTrustByNode.ts index 8ebe7660b..bad8dc219 100644 --- a/src/client/service/gestaltsGestaltTrustByNode.ts +++ b/src/client/service/gestaltsGestaltTrustByNode.ts @@ -1,7 +1,7 @@ import type * as grpc from '@grpc/grpc-js'; 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'; diff --git a/src/client/service/identitiesAuthenticate.ts b/src/client/service/identitiesAuthenticate.ts index e2e39162f..05c3e05d3 100644 --- a/src/client/service/identitiesAuthenticate.ts +++ b/src/client/service/identitiesAuthenticate.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 { ProviderId } from '../../identities/types'; import type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; -import { errors as identitiesErrors } from '../../identities'; -import { validateSync, utils as validationUtils } from '../../validation'; +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'; diff --git a/src/client/service/identitiesAuthenticatedGet.ts b/src/client/service/identitiesAuthenticatedGet.ts index d344c14a6..82262f89d 100644 --- a/src/client/service/identitiesAuthenticatedGet.ts +++ b/src/client/service/identitiesAuthenticatedGet.ts @@ -1,6 +1,6 @@ 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'; diff --git a/src/client/service/identitiesClaim.ts b/src/client/service/identitiesClaim.ts index 2367998df..93a947e42 100644 --- a/src/client/service/identitiesClaim.ts +++ b/src/client/service/identitiesClaim.ts @@ -1,15 +1,16 @@ import type * as grpc from '@grpc/grpc-js'; 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 type Logger from '@matrixai/logger'; -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 * 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'; diff --git a/src/client/service/identitiesInfoConnectedGet.ts b/src/client/service/identitiesInfoConnectedGet.ts index f232e3a4d..b9d7ac441 100644 --- a/src/client/service/identitiesInfoConnectedGet.ts +++ b/src/client/service/identitiesInfoConnectedGet.ts @@ -1,6 +1,6 @@ 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, diff --git a/src/client/service/identitiesInfoGet.ts b/src/client/service/identitiesInfoGet.ts index 31a8139c8..5f456dac5 100644 --- a/src/client/service/identitiesInfoGet.ts +++ b/src/client/service/identitiesInfoGet.ts @@ -1,6 +1,6 @@ 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, diff --git a/src/client/service/identitiesProvidersList.ts b/src/client/service/identitiesProvidersList.ts index 8fa533a9c..35751c3fb 100644 --- a/src/client/service/identitiesProvidersList.ts +++ b/src/client/service/identitiesProvidersList.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; function identitiesProvidersList({ diff --git a/src/client/service/identitiesTokenDelete.ts b/src/client/service/identitiesTokenDelete.ts index 69bba5775..347e37bb4 100644 --- a/src/client/service/identitiesTokenDelete.ts +++ b/src/client/service/identitiesTokenDelete.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 { IdentityId, ProviderId } from '../../identities/types'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; import type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/identitiesTokenGet.ts b/src/client/service/identitiesTokenGet.ts index cb7987156..7844382a8 100644 --- a/src/client/service/identitiesTokenGet.ts +++ b/src/client/service/identitiesTokenGet.ts @@ -1,10 +1,11 @@ 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 { IdentityId, ProviderId } from '../../identities/types'; import type Logger from '@matrixai/logger'; -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 identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; diff --git a/src/client/service/identitiesTokenPut.ts b/src/client/service/identitiesTokenPut.ts index cb532d4c1..babfd8db7 100644 --- a/src/client/service/identitiesTokenPut.ts +++ b/src/client/service/identitiesTokenPut.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 { IdentityId, ProviderId, TokenData } from '../../identities/types'; import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; import type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/index.ts b/src/client/service/index.ts index dc7ac4ff7..1e74eb9d8 100644 --- a/src/client/service/index.ts +++ b/src/client/service/index.ts @@ -1,6 +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, @@ -10,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'; diff --git a/src/client/service/keysCertsChainGet.ts b/src/client/service/keysCertsChainGet.ts index b62c85783..6290a313c 100644 --- a/src/client/service/keysCertsChainGet.ts +++ b/src/client/service/keysCertsChainGet.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysCertsChainGet({ diff --git a/src/client/service/keysCertsGet.ts b/src/client/service/keysCertsGet.ts index 6d63cfba8..eabde463b 100644 --- a/src/client/service/keysCertsGet.ts +++ b/src/client/service/keysCertsGet.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysCertsGet({ diff --git a/src/client/service/keysDecrypt.ts b/src/client/service/keysDecrypt.ts index 05e68e066..ed1776cda 100644 --- a/src/client/service/keysDecrypt.ts +++ b/src/client/service/keysDecrypt.ts @@ -1,8 +1,8 @@ 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 Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysDecrypt({ diff --git a/src/client/service/keysEncrypt.ts b/src/client/service/keysEncrypt.ts index 2c84444fb..35159f870 100644 --- a/src/client/service/keysEncrypt.ts +++ b/src/client/service/keysEncrypt.ts @@ -1,8 +1,8 @@ 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 Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysEncrypt({ diff --git a/src/client/service/keysKeyPairRenew.ts b/src/client/service/keysKeyPairRenew.ts index c2d88acca..dcd90d7c1 100644 --- a/src/client/service/keysKeyPairRenew.ts +++ b/src/client/service/keysKeyPairRenew.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function keysKeyPairRenew({ diff --git a/src/client/service/keysKeyPairReset.ts b/src/client/service/keysKeyPairReset.ts index 82e73277e..87498f733 100644 --- a/src/client/service/keysKeyPairReset.ts +++ b/src/client/service/keysKeyPairReset.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function keysKeyPairReset({ diff --git a/src/client/service/keysKeyPairRoot.ts b/src/client/service/keysKeyPairRoot.ts index 9f20b410b..7bfc95549 100644 --- a/src/client/service/keysKeyPairRoot.ts +++ b/src/client/service/keysKeyPairRoot.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysKeyPairRoot({ diff --git a/src/client/service/keysPasswordChange.ts b/src/client/service/keysPasswordChange.ts index 21ad66425..639e60ac9 100644 --- a/src/client/service/keysPasswordChange.ts +++ b/src/client/service/keysPasswordChange.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function keysPasswordChange({ diff --git a/src/client/service/keysSign.ts b/src/client/service/keysSign.ts index 14f722a0c..b998e0561 100644 --- a/src/client/service/keysSign.ts +++ b/src/client/service/keysSign.ts @@ -1,8 +1,8 @@ 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 Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; function keysSign({ diff --git a/src/client/service/keysVerify.ts b/src/client/service/keysVerify.ts index 26918bc3d..efbfb7b4c 100644 --- a/src/client/service/keysVerify.ts +++ b/src/client/service/keysVerify.ts @@ -1,9 +1,9 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function keysVerify({ diff --git a/src/client/service/nodesAdd.ts b/src/client/service/nodesAdd.ts index 7cbfb739f..cda85ee22 100644 --- a/src/client/service/nodesAdd.ts +++ b/src/client/service/nodesAdd.ts @@ -1,12 +1,13 @@ 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, 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 type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/nodesClaim.ts b/src/client/service/nodesClaim.ts index b82731c05..3c165d579 100644 --- a/src/client/service/nodesClaim.ts +++ b/src/client/service/nodesClaim.ts @@ -1,12 +1,13 @@ 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 { NotificationsManager } from '../../notifications'; +import type NotificationsManager from '../../notifications/NotificationsManager'; import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; import type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/nodesFind.ts b/src/client/service/nodesFind.ts index b8cb887db..284e50748 100644 --- a/src/client/service/nodesFind.ts +++ b/src/client/service/nodesFind.ts @@ -1,11 +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 type Logger from '@matrixai/logger'; -import { utils as nodesUtils } from '../../nodes'; -import { utils as grpcUtils } from '../../grpc'; -import { validateSync, utils as validationUtils } from '../../validation'; +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'; diff --git a/src/client/service/nodesPing.ts b/src/client/service/nodesPing.ts index 2356f2072..449905cc7 100644 --- a/src/client/service/nodesPing.ts +++ b/src/client/service/nodesPing.ts @@ -1,11 +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 type Logger from '@matrixai/logger'; -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'; diff --git a/src/client/service/notificationsClear.ts b/src/client/service/notificationsClear.ts index 7d2ba80cc..2fd077c9b 100644 --- a/src/client/service/notificationsClear.ts +++ b/src/client/service/notificationsClear.ts @@ -1,8 +1,8 @@ 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 Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function notificationsClear({ diff --git a/src/client/service/notificationsRead.ts b/src/client/service/notificationsRead.ts index f8bccc692..630940764 100644 --- a/src/client/service/notificationsRead.ts +++ b/src/client/service/notificationsRead.ts @@ -1,8 +1,8 @@ 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 Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; +import * as grpcUtils from '../../grpc/utils'; import * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifications_pb'; function notificationsRead({ diff --git a/src/client/service/notificationsSend.ts b/src/client/service/notificationsSend.ts index c30512611..4ff96fea6 100644 --- a/src/client/service/notificationsSend.ts +++ b/src/client/service/notificationsSend.ts @@ -1,12 +1,13 @@ 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 type Logger from '@matrixai/logger'; -import { utils as grpcUtils } from '../../grpc'; -import { utils as notificationsUtils } from '../../notifications'; -import { validateSync, utils as validationUtils } from '../../validation'; +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'; diff --git a/src/client/service/vaultsPermissionGet.ts b/src/client/service/vaultsPermissionGet.ts index 8dd0866c3..1682044ad 100644 --- a/src/client/service/vaultsPermissionGet.ts +++ b/src/client/service/vaultsPermissionGet.ts @@ -1,7 +1,7 @@ +import type * as grpc from '@grpc/grpc-js'; 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'; diff --git a/src/client/utils/utils.ts b/src/client/utils/utils.ts index f922128bb..d49173a6f 100644 --- a/src/client/utils/utils.ts +++ b/src/client/utils/utils.ts @@ -8,8 +8,8 @@ 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'; /** @@ -130,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/grpc/GRPCClient.ts b/src/grpc/GRPCClient.ts index 22a7c65e5..4e88291a1 100644 --- a/src/grpc/GRPCClient.ts +++ b/src/grpc/GRPCClient.ts @@ -267,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/utils/utils.ts b/src/grpc/utils/utils.ts index 7db50484c..4efb787f3 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -28,11 +28,14 @@ import type { AsyncGeneratorDuplexStreamClient, } from '../types'; import type { CertificatePemChain, PrivateKeyPem } from '../../keys/types'; +import type { Host, Port } from '../../network/types'; +import type { NodeId } from '../../nodes/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 nodesUtils from '../../nodes/utils'; import { promisify, promise, never } from '../../utils/utils'; /** @@ -182,7 +185,10 @@ function fromError( * Use this on the receiving side to receive exceptions */ function toError(e: ServiceError): errors.ErrorPolykey { - const errorData = e.metadata.get('error')[0] as string; + const errorData = e.metadata.get('error')[0].toString(); + const nodeId = e.metadata.get('nodeId')[0].toString(); + const host = e.metadata.get('host')[0].toString(); + const port = parseInt(e.metadata.get('port')[0].toString()); // Grpc.status is an enum // this will iterate the enum values then enum keys // they will all be of string type @@ -193,7 +199,14 @@ function toError(e: ServiceError): errors.ErrorPolykey { if (isNaN(parseInt(key)) && e.code === grpc.status[key]) { if (key === 'UNKNOWN' && errorData != null) { const error: Error = JSON.parse(errorData, reviver); - return new errors.ErrorPolykeyRemote(error.message, { cause: error }); + return new errors.ErrorPolykeyRemote(error.message, { + data: { + nodeId, + host, + port, + }, + cause: error, + }); } else { return new grpcErrors.ErrorGRPCClientCall(e.message, { data: { @@ -215,16 +228,13 @@ function toError(e: ServiceError): errors.ErrorPolykey { * serialises other errors */ function replacer(key: string, value: any): any { - if (value instanceof AbstractError) { - // Include the standard properties from an AbstractError + if (value instanceof AggregateError) { + // AggregateError has an `errors` property return { - type: value.name, + type: value.constructor.name, data: { - description: value.description, + errors: value.errors, message: value.message, - timestamp: value.timestamp, - data: value.data, - cause: value.cause, stack: value.stack, }, }; @@ -261,14 +271,16 @@ function sensitiveReplacer(key: string, value: any) { * Error constructors for non-Polykey errors * Allows these errors to be reconstructed from GRPC metadata */ -const otherErrors = { - Error: Error, - EvalError: EvalError, - RangeError: RangeError, - ReferenceError: ReferenceError, - SyntaxError: SyntaxError, - TypeError: TypeError, - URIError: URIError, +const standardErrors = { + Error, + TypeError, + SyntaxError, + ReferenceError, + EvalError, + RangeError, + URIError, + AggregateError, + AbstractError, }; /** @@ -285,34 +297,58 @@ function reviver(key: string, value: any): any { typeof value.type === 'string' && typeof value.data === 'object' ) { - const message = value.data.message ?? ''; - if (value.type in errors) { - const error = new errors[value.type](message, { - timestamp: value.data.timestamp, - data: value.data.data, - cause: value.data.cause, - }); - error.exitCode = value.data.exitCode; - if (value.data.stack) { - error.stack = value.data.stack; - } - return error; - } else if (value.type in otherErrors) { - const error = new otherErrors[value.type](message); - if (value.data.stack) { - error.stack = value.data.stack; + 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; } - return error; - } else { - const error = new errors.ErrorPolykeyUnknown('', { data: value }); - if (value.data.stack) { - error.stack = value.data.stack; + } 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; } - return error; } + // Other values are returned as-is + return value; } else if (key === '') { - // The value is not an error - const error = new errors.ErrorPolykeyUnknown('', { data: value }); + // 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 @@ -334,6 +370,9 @@ function reviver(key: string, value: any): any { */ function promisifyUnaryCall( client: Client, + nodeId: NodeId, + host: Host, + port: Port, f: (...args: any[]) => ClientUnaryCall, ): (...args: any[]) => PromiseUnaryCall { return (...args) => { @@ -345,6 +384,9 @@ function promisifyUnaryCall( const { p: pMeta, resolveP: resolveMetaP } = promise(); const callback = (error: ServiceError, ...values) => { if (error != null) { + error.metadata.set('nodeId', nodesUtils.encodeNodeId(nodeId)); + error.metadata.set('host', host); + error.metadata.set('port', port.toString()); rejectP(toError(error)); return; } @@ -370,12 +412,21 @@ function promisifyUnaryCall( */ function generatorReadable( stream: ClientReadableStream, + nodeId: NodeId, + host: Host, + port: Port, ): AsyncGeneratorReadableStream>; function generatorReadable( stream: ServerReadableStream, + nodeId: NodeId, + host: Host, + port: Port, ): AsyncGeneratorReadableStream>; function generatorReadable( stream: ClientReadableStream | ServerReadableStream, + nodeId: NodeId, + host: Host, + port: Port, ) { const gf = async function* () { try { @@ -397,6 +448,9 @@ function generatorReadable( } } catch (e) { stream.destroy(); + e.metadata.set('nodeId', nodesUtils.encodeNodeId(nodeId)); + e.metadata.set('host', host); + e.metadata.set('port', port.toString()); throw toError(e); } }; @@ -414,6 +468,9 @@ function generatorReadable( */ function promisifyReadableStreamCall( client: grpc.Client, + nodeId: NodeId, + host: Host, + port: Port, f: (...args: any[]) => ClientReadableStream, ): ( ...args: any[] @@ -426,6 +483,9 @@ function promisifyReadableStreamCall( }); const g = generatorReadable( stream, + nodeId, + host, + port, ) as AsyncGeneratorReadableStreamClient>; g.meta = pMeta; return g; @@ -484,6 +544,9 @@ function generatorWritable( */ function promisifyWritableStreamCall( client: grpc.Client, + nodeId: NodeId, + host: Host, + port: Port, f: (...args: any[]) => ClientWritableStream, ): ( ...args: any[] @@ -499,6 +562,9 @@ function promisifyWritableStreamCall( }; const callback = (error, ...values) => { if (error != null) { + error.metadata.set('nodeId', nodesUtils.encodeNodeId(nodeId)); + error.metadata.set('host', host); + error.metadata.set('port', port.toString()); return rejectP(toError(error)); } return resolveP(values.length === 1 ? values[0] : values); @@ -531,17 +597,26 @@ function promisifyWritableStreamCall( */ function generatorDuplex( stream: ClientDuplexStream, + nodeId: NodeId, + host: Host, + port: Port, sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ServerDuplexStream, + nodeId: NodeId, + host: Host, + port: Port, sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ClientDuplexStream | ServerDuplexStream, + nodeId: NodeId, + host: Host, + port: Port, sensitive: boolean = false, ) { - const gR = generatorReadable(stream as any); + const gR = generatorReadable(stream as any, nodeId, host, port); const gW = generatorWritable(stream as any, sensitive); const gf = async function* () { let vR: any, vW: any; @@ -591,6 +666,9 @@ function generatorDuplex( */ function promisifyDuplexStreamCall( client: grpc.Client, + nodeId: NodeId, + host: Host, + port: Port, f: (...args: any[]) => ClientDuplexStream, ): ( ...args: any[] @@ -607,6 +685,9 @@ function promisifyDuplexStreamCall( }); const g = generatorDuplex( stream, + nodeId, + host, + port, false, ) as AsyncGeneratorDuplexStreamClient< TRead, diff --git a/tests/client/service/agentLockAll.test.ts b/tests/client/service/agentLockAll.test.ts index 9fd74aab4..a024cc05c 100644 --- a/tests/client/service/agentLockAll.test.ts +++ b/tests/client/service/agentLockAll.test.ts @@ -89,6 +89,7 @@ describe('agentLockall', () => { nodeId: keyManager.getNodeId(), host: '127.0.0.1' as Host, port: grpcServer.getPort(), + timeout: 5000, logger, }); }); From 30eb4bd47964c97c5389710f062ab47be5cdf1ca Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 18 May 2022 18:26:27 +1000 Subject: [PATCH 38/74] feat: adding transactions to agent service handlers --- src/agent/service/nodesChainDataGet.ts | 7 +- .../service/nodesClosestLocalNodesGet.ts | 12 +- src/agent/service/nodesCrossSignClaim.ts | 3 +- .../service/nodesHolePunchMessageSend.ts | 25 +++-- src/agent/service/notificationsSend.ts | 9 +- src/agent/service/vaultsGitInfoGet.ts | 105 ++++++++++-------- src/agent/service/vaultsGitPackGet.ts | 89 ++++++++------- src/agent/service/vaultsScan.ts | 27 +++-- src/nodes/NodeConnectionManager.ts | 5 +- src/nodes/NodeGraph.ts | 11 +- src/nodes/NodeManager.ts | 9 +- src/vaults/VaultManager.ts | 5 +- tests/agent/service/notificationsSend.test.ts | 1 + 13 files changed, 185 insertions(+), 123 deletions(-) diff --git a/src/agent/service/nodesChainDataGet.ts b/src/agent/service/nodesChainDataGet.ts index f2970228f..492c8ca73 100644 --- a/src/agent/service/nodesChainDataGet.ts +++ b/src/agent/service/nodesChainDataGet.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +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'; @@ -11,9 +12,11 @@ import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; */ function nodesChainDataGet({ sigchain, + db, logger, }: { sigchain: Sigchain; + db: DB; logger: Logger; }) { return async ( @@ -22,7 +25,9 @@ function nodesChainDataGet({ ): 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) { diff --git a/src/agent/service/nodesClosestLocalNodesGet.ts b/src/agent/service/nodesClosestLocalNodesGet.ts index ee031f478..bd562bbe5 100644 --- a/src/agent/service/nodesClosestLocalNodesGet.ts +++ b/src/agent/service/nodesClosestLocalNodesGet.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type NodeConnectionManager from '../../nodes/NodeConnectionManager'; import type { NodeId } from '../../nodes/types'; import type Logger from '@matrixai/logger'; @@ -15,9 +16,11 @@ import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; */ function nodesClosestLocalNodesGet({ nodeConnectionManager, + db, logger, }: { nodeConnectionManager: NodeConnectionManager; + db: DB; logger: Logger; }) { return async ( @@ -42,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(); diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index b21ed882c..a24420142 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -7,7 +7,6 @@ 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 type Logger from '@matrixai/logger'; -import { withF } from '@matrixai/resources'; import * as grpcUtils from '../../grpc/utils'; import * as claimsUtils from '../../claims/utils'; import * as claimsErrors from '../../claims/errors'; @@ -34,7 +33,7 @@ function nodesCrossSignClaim({ ) => { const genClaims = grpcUtils.generatorDuplex(call, true); try { - await withF([db.transaction()], async ([tran]) => { + await db.withTransactionF(async (tran) => { const readStatus = await genClaims.read(); // If nothing to read, end and destroy if (readStatus.done) { diff --git a/src/agent/service/nodesHolePunchMessageSend.ts b/src/agent/service/nodesHolePunchMessageSend.ts index 592d0f482..c1b681054 100644 --- a/src/agent/service/nodesHolePunchMessageSend.ts +++ b/src/agent/service/nodesHolePunchMessageSend.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type NodeManager from '../../nodes/NodeManager'; import type NodeConnectionManager from '../../nodes/NodeConnectionManager'; import type KeyManager from '../../keys/KeyManager'; @@ -16,11 +17,13 @@ function nodesHolePunchMessageSend({ keyManager, nodeManager, nodeConnectionManager, + db, logger, }: { keyManager: KeyManager; nodeManager: NodeManager; nodeConnectionManager: NodeConnectionManager; + db: DB; logger: Logger; }) { return async ( @@ -54,16 +57,18 @@ 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) { diff --git a/src/agent/service/notificationsSend.ts b/src/agent/service/notificationsSend.ts index 6baef6f9f..07aaf0933 100644 --- a/src/agent/service/notificationsSend.ts +++ b/src/agent/service/notificationsSend.ts @@ -2,15 +2,18 @@ import type * as grpc from '@grpc/grpc-js'; import type NotificationsManager from '../../notifications/NotificationsManager'; import type * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifications_pb'; 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 ( @@ -21,10 +24,12 @@ 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) { diff --git a/src/agent/service/vaultsGitInfoGet.ts b/src/agent/service/vaultsGitInfoGet.ts index 6f4ae9873..4a9893985 100644 --- a/src/agent/service/vaultsGitInfoGet.ts +++ b/src/agent/service/vaultsGitInfoGet.ts @@ -1,3 +1,4 @@ +import type { DB } from '@matrixai/db'; import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type ACL from '../../acl/ACL'; @@ -15,11 +16,13 @@ import * as agentErrors from '../errors'; function vaultsGitInfoGet({ vaultManager, acl, + db, logger, connectionInfoGet, }: { vaultManager: VaultManager; acl: ACL; + db: DB; logger: Logger; connectionInfoGet: ConnectionInfoGet; }) { @@ -35,56 +38,64 @@ function vaultsGitInfoGet({ } 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 (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); - if (permissions == null) { - throw new vaultsErrors.ErrorVaultsPermissionDenied( - `No permissions found for ${nodeIdEncoded}`, + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + vaultNameOrId as VaultName, + tran, ); - } - 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, - )}`, + 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 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 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); diff --git a/src/agent/service/vaultsGitPackGet.ts b/src/agent/service/vaultsGitPackGet.ts index e96398529..988dda47c 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -1,4 +1,5 @@ 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'; @@ -16,11 +17,13 @@ import * as agentErrors from '../errors'; function vaultsGitPackGet({ vaultManager, acl, + db, logger, connectionInfoGet, }: { vaultManager: VaultManager; acl: ACL; + db: DB; logger: Logger; connectionInfoGet: ConnectionInfoGet; }) { @@ -48,49 +51,55 @@ function vaultsGitPackGet({ 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) { - // Throwing permission error to hide information about vaults existence - throw new vaultsErrors.ErrorVaultsPermissionDenied( - `No permissions found for ${nodeIdEncoded}`, + await db.withTransactionF(async (tran) => { + let vaultId = await vaultManager.getVaultId( + vaultNameOrId as VaultName, + tran, ); - } - // 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) { - throw new vaultsErrors.ErrorVaultsPermissionDenied( - `${nodeIdEncoded} does not have permission to ${actionType} from vault ${vaultsUtils.encodeVaultId( - vaultId, - )}`, + 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(), ); - } - 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)); - await genDuplex.write(response); - resolve(); - }); - sideBand.on('error', (err) => { - reject(err); + 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); + 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); } catch (e) { diff --git a/src/agent/service/vaultsScan.ts b/src/agent/service/vaultsScan.ts index bd7cb004b..2fd04d5e5 100644 --- a/src/agent/service/vaultsScan.ts +++ b/src/agent/service/vaultsScan.ts @@ -1,4 +1,5 @@ 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'; @@ -12,10 +13,12 @@ function vaultsScan({ vaultManager, logger, connectionInfoGet, + db, }: { vaultManager: VaultManager; logger: Logger; connectionInfoGet: ConnectionInfoGet; + db: DB; }) { return async ( call: grpc.ServerWritableStream, @@ -31,17 +34,19 @@ 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); diff --git a/src/nodes/NodeConnectionManager.ts b/src/nodes/NodeConnectionManager.ts index 23572a0c7..812b18832 100644 --- a/src/nodes/NodeConnectionManager.ts +++ b/src/nodes/NodeConnectionManager.ts @@ -11,6 +11,7 @@ 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'; @@ -448,6 +449,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) @@ -456,9 +458,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) { diff --git a/src/nodes/NodeGraph.ts b/src/nodes/NodeGraph.ts index 7cd35ee13..ddf2ff7b3 100644 --- a/src/nodes/NodeGraph.ts +++ b/src/nodes/NodeGraph.ts @@ -110,6 +110,7 @@ class NodeGraph { /** * 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()) @@ -136,16 +137,21 @@ class NodeGraph { * 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( @@ -255,6 +261,7 @@ class NodeGraph { /** * Removes a node from the bucket database * @param nodeId + * @param tran */ @ready(new nodesErrors.ErrorNodeGraphNotRunning()) public async unsetNode(nodeId: NodeId, tran?: DBTransaction): Promise { diff --git a/src/nodes/NodeManager.ts b/src/nodes/NodeManager.ts index 61820d706..fe57b8001 100644 --- a/src/nodes/NodeManager.ts +++ b/src/nodes/NodeManager.ts @@ -318,11 +318,14 @@ class NodeManager { /** * 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 { - // FIXME: use tran - return await this.nodeGraph.knowsNode(targetNodeId); + public async knowsNode( + targetNodeId: NodeId, + tran?: DBTransaction, + ): Promise { + return await this.nodeGraph.knowsNode(targetNodeId, tran); } /** diff --git a/src/vaults/VaultManager.ts b/src/vaults/VaultManager.ts index beb8a525a..2f8fe364f 100644 --- a/src/vaults/VaultManager.ts +++ b/src/vaults/VaultManager.ts @@ -864,9 +864,10 @@ class VaultManager { vaultPermissions: VaultAction[]; }> { if (tran == null) { - const fml = (tran) => this.handleScanVaults(nodeId, tran); + // Lambda to maintain `this` context + const handleScanVaults = (tran) => this.handleScanVaults(nodeId, tran); return yield* this.db.withTransactionG(async function* (tran) { - return yield* fml(tran); + return yield* handleScanVaults(tran); }); } diff --git a/tests/agent/service/notificationsSend.test.ts b/tests/agent/service/notificationsSend.test.ts index 5d51289e0..c0b79e91c 100644 --- a/tests/agent/service/notificationsSend.test.ts +++ b/tests/agent/service/notificationsSend.test.ts @@ -139,6 +139,7 @@ describe('notificationsSend', () => { notificationsSend: notificationsSend({ notificationsManager, logger, + db, }), }; grpcServer = new GRPCServer({ logger }); From c0f1e8c956eab1b463701709fadf71ccd37f79c1 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Thu, 19 May 2022 11:05:04 +1000 Subject: [PATCH 39/74] fix: toError deserialization There was a bug with the `fromJSON` method where it couldn't deserialise an error with an undefined cause (because this is removed by the replacer). --- src/ErrorPolykey.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ErrorPolykey.ts b/src/ErrorPolykey.ts index 4ee452242..b7286859e 100644 --- a/src/ErrorPolykey.ts +++ b/src/ErrorPolykey.ts @@ -17,8 +17,7 @@ class ErrorPolykey extends AbstractError { typeof json.data.message !== 'string' || isNaN(Date.parse(json.data.timestamp)) || typeof json.data.data !== 'object' || - typeof json.data.exitCode !== 'string' || - !('cause' in json.data) || + typeof json.data.exitCode !== 'number' || ('stack' in json.data && typeof json.data.stack !== 'string') ) { throw new TypeError(`Cannot decode JSON to ${this.name}`); From bcff36435021fe58aaaf2b7891467e48b9aa162c Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Thu, 19 May 2022 16:05:24 +1000 Subject: [PATCH 40/74] feat: adding metadata of sending node to errors --- src/agent/GRPCClientAgent.ts | 80 ++-- src/agent/service/nodesCrossSignClaim.ts | 3 +- src/agent/service/vaultsGitPackGet.ts | 6 +- src/client/GRPCClientClient.ts | 512 ++++++++++++++--------- src/grpc/utils/utils.ts | 88 ++-- 5 files changed, 408 insertions(+), 281 deletions(-) diff --git a/src/agent/GRPCClientAgent.ts b/src/agent/GRPCClientAgent.ts index dd68e2db5..bfc1c4d65 100644 --- a/src/agent/GRPCClientAgent.ts +++ b/src/agent/GRPCClientAgent.ts @@ -79,9 +79,11 @@ class GRPCClientAgent extends GRPCClient { public echo(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.echo, )(...args); } @@ -95,9 +97,11 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsGitInfoGet, )(...args); } @@ -112,9 +116,11 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyDuplexStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsGitPackGet, )(...args); } @@ -128,9 +134,11 @@ class GRPCClientAgent extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsScan, )(...args); } @@ -139,9 +147,11 @@ class GRPCClientAgent extends GRPCClient { public nodesClosestLocalNodesGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesClosestLocalNodesGet, )(...args); } @@ -150,9 +160,11 @@ class GRPCClientAgent extends GRPCClient { public nodesClaimsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesClaimsGet, )(...args); } @@ -161,9 +173,11 @@ class GRPCClientAgent extends GRPCClient { public nodesChainDataGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesChainDataGet, )(...args); } @@ -172,9 +186,11 @@ class GRPCClientAgent extends GRPCClient { public nodesHolePunchMessageSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesHolePunchMessageSend, )(...args); } @@ -183,9 +199,11 @@ class GRPCClientAgent extends GRPCClient { public notificationsSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.notificationsSend, )(...args); } @@ -203,9 +221,11 @@ class GRPCClientAgent extends GRPCClient { nodesPB.CrossSign >( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesCrossSignClaim, )(...args); } diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index a24420142..f0a3e2a9a 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -31,7 +31,8 @@ function nodesCrossSignClaim({ return async ( call: grpc.ServerDuplexStream, ) => { - const genClaims = grpcUtils.generatorDuplex(call, true); + const nodeId = keyManager.getNodeId(); + const genClaims = grpcUtils.generatorDuplex(call, { nodeId }, true); try { await db.withTransactionF(async (tran) => { const readStatus = await genClaims.read(); diff --git a/src/agent/service/vaultsGitPackGet.ts b/src/agent/service/vaultsGitPackGet.ts index 988dda47c..8d9561512 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -4,6 +4,7 @@ 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'; @@ -18,19 +19,22 @@ 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, ): Promise => { - const genDuplex = grpcUtils.generatorDuplex(call, true); + const nodeId = keyManager.getNodeId(); + const genDuplex = grpcUtils.generatorDuplex(call, { nodeId }, true); try { const clientBodyBuffers: Uint8Array[] = []; const clientRequest = (await genDuplex.read()).value; diff --git a/src/client/GRPCClientClient.ts b/src/client/GRPCClientClient.ts index 87ff45b6c..e866ec475 100644 --- a/src/client/GRPCClientClient.ts +++ b/src/client/GRPCClientClient.ts @@ -91,9 +91,11 @@ class GRPCClientClient extends GRPCClient { public agentStatus(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.agentStatus, )(...args); } @@ -102,9 +104,11 @@ class GRPCClientClient extends GRPCClient { public agentStop(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.agentStop, )(...args); } @@ -113,9 +117,11 @@ class GRPCClientClient extends GRPCClient { public agentUnlock(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.agentUnlock, )(...args); } @@ -124,9 +130,11 @@ class GRPCClientClient extends GRPCClient { public agentLockAll(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.agentLockAll, )(...args); } @@ -140,9 +148,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsList, )(...args); } @@ -151,9 +161,11 @@ class GRPCClientClient extends GRPCClient { public vaultsCreate(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsCreate, )(...args); } @@ -162,9 +174,11 @@ class GRPCClientClient extends GRPCClient { public vaultsRename(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsRename, )(...args); } @@ -173,9 +187,11 @@ class GRPCClientClient extends GRPCClient { public vaultsDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsDelete, )(...args); } @@ -184,9 +200,11 @@ class GRPCClientClient extends GRPCClient { public vaultsClone(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsClone, )(...args); } @@ -195,9 +213,11 @@ class GRPCClientClient extends GRPCClient { public vaultsPull(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsPull, )(...args); } @@ -211,9 +231,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsScan, )(...args); } @@ -222,9 +244,11 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsPermissionGet, )(...args); } @@ -233,9 +257,11 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionSet(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsPermissionSet, )(...args); } @@ -244,9 +270,11 @@ class GRPCClientClient extends GRPCClient { public vaultsPermissionUnset(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsPermissionUnset, )(...args); } @@ -260,9 +288,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsList, )(...args); } @@ -271,9 +301,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsMkdir(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsMkdir, )(...args); } @@ -282,9 +314,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsDelete, )(...args); } @@ -293,9 +327,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsEdit(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsEdit, )(...args); } @@ -304,9 +340,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsGet, )(...args); } @@ -315,9 +353,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsStat(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsStat, )(...args); } @@ -326,9 +366,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsRename(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsRename, )(...args); } @@ -337,9 +379,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsNew(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsNew, )(...args); } @@ -348,9 +392,11 @@ class GRPCClientClient extends GRPCClient { public vaultsSecretsNewDir(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsSecretsNewDir, )(...args); } @@ -359,9 +405,11 @@ class GRPCClientClient extends GRPCClient { public vaultsVersion(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsVersion, )(...args); } @@ -375,9 +423,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.vaultsLog, )(...args); } @@ -386,9 +436,11 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairRoot(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysKeyPairRoot, )(...args); } @@ -397,9 +449,11 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairReset(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysKeyPairReset, )(...args); } @@ -408,9 +462,11 @@ class GRPCClientClient extends GRPCClient { public keysKeyPairRenew(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysKeyPairRenew, )(...args); } @@ -419,9 +475,11 @@ class GRPCClientClient extends GRPCClient { public keysEncrypt(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysEncrypt, )(...args); } @@ -430,9 +488,11 @@ class GRPCClientClient extends GRPCClient { public keysDecrypt(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysDecrypt, )(...args); } @@ -441,9 +501,11 @@ class GRPCClientClient extends GRPCClient { public keysSign(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysSign, )(...args); } @@ -452,9 +514,11 @@ class GRPCClientClient extends GRPCClient { public keysVerify(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysVerify, )(...args); } @@ -463,9 +527,11 @@ class GRPCClientClient extends GRPCClient { public keysPasswordChange(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysPasswordChange, )(...args); } @@ -474,9 +540,11 @@ class GRPCClientClient extends GRPCClient { public keysCertsGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysCertsGet, )(...args); } @@ -490,9 +558,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.keysCertsChainGet, )(...args); } @@ -506,9 +576,11 @@ class GRPCClientClient extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltList, )(...args); } @@ -517,9 +589,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltGetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltGetByIdentity, )(...args); } @@ -528,9 +602,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltGetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltGetByNode, )(...args); } @@ -539,9 +615,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsDiscoveryByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsDiscoveryByNode, )(...args); } @@ -550,9 +628,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsDiscoveryByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsDiscoveryByIdentity, )(...args); } @@ -561,9 +641,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsGetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsGetByNode, )(...args); } @@ -572,9 +654,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsGetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsGetByIdentity, )(...args); } @@ -583,9 +667,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsSetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsSetByNode, )(...args); } @@ -594,9 +680,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsSetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsSetByIdentity, )(...args); } @@ -605,9 +693,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsUnsetByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsUnsetByNode, )(...args); } @@ -616,9 +706,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsActionsUnsetByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsActionsUnsetByIdentity, )(...args); } @@ -627,9 +719,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltTrustByNode(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltTrustByNode, )(...args); } @@ -638,9 +732,11 @@ class GRPCClientClient extends GRPCClient { public gestaltsGestaltTrustByIdentity(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.gestaltsGestaltTrustByIdentity, )(...args); } @@ -649,9 +745,11 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenPut(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesTokenPut, )(...args); } @@ -660,9 +758,11 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenGet(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesTokenGet, )(...args); } @@ -671,9 +771,11 @@ class GRPCClientClient extends GRPCClient { public identitiesTokenDelete(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesTokenDelete, )(...args); } @@ -682,9 +784,11 @@ class GRPCClientClient extends GRPCClient { public identitiesProvidersList(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesProvidersList, )(...args); } @@ -693,9 +797,11 @@ class GRPCClientClient extends GRPCClient { public nodesAdd(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesAdd, )(...args); } @@ -704,9 +810,11 @@ class GRPCClientClient extends GRPCClient { public nodesPing(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesPing, )(...args); } @@ -715,9 +823,11 @@ class GRPCClientClient extends GRPCClient { public nodesClaim(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesClaim, )(...args); } @@ -726,9 +836,11 @@ class GRPCClientClient extends GRPCClient { public nodesFind(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.nodesFind, )(...args); } @@ -737,9 +849,11 @@ class GRPCClientClient extends GRPCClient { public identitiesAuthenticate(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesAuthenticate, )(...args); } @@ -748,9 +862,11 @@ class GRPCClientClient extends GRPCClient { public identitiesInfoConnectedGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesInfoConnectedGet, )(...args); } @@ -759,9 +875,11 @@ class GRPCClientClient extends GRPCClient { public identitiesInfoGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesInfoGet, )(...args); } @@ -770,9 +888,11 @@ class GRPCClientClient extends GRPCClient { public identitiesClaim(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesClaim, )(...args); } @@ -781,9 +901,11 @@ class GRPCClientClient extends GRPCClient { public identitiesAuthenticatedGet(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.identitiesAuthenticatedGet, )(...args); } @@ -792,9 +914,11 @@ class GRPCClientClient extends GRPCClient { public notificationsSend(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.notificationsSend, )(...args); } @@ -803,9 +927,11 @@ class GRPCClientClient extends GRPCClient { public notificationsRead(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.notificationsRead, )(...args); } @@ -814,9 +940,11 @@ class GRPCClientClient extends GRPCClient { public notificationsClear(...args) { return grpcUtils.promisifyUnaryCall( this.client, - this.nodeId, - this.host, - this.port, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + }, this.client.notificationsClear, )(...args); } diff --git a/src/grpc/utils/utils.ts b/src/grpc/utils/utils.ts index 4efb787f3..4b7335fd5 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -28,14 +28,13 @@ import type { AsyncGeneratorDuplexStreamClient, } from '../types'; import type { CertificatePemChain, PrivateKeyPem } from '../../keys/types'; -import type { Host, Port } from '../../network/types'; -import type { NodeId } from '../../nodes/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 nodesUtils from '../../nodes/utils'; +import * as networkUtils from '../../network/utils'; import { promisify, promise, never } from '../../utils/utils'; /** @@ -186,9 +185,7 @@ function fromError( */ function toError(e: ServiceError): errors.ErrorPolykey { const errorData = e.metadata.get('error')[0].toString(); - const nodeId = e.metadata.get('nodeId')[0].toString(); - const host = e.metadata.get('host')[0].toString(); - const port = parseInt(e.metadata.get('port')[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 @@ -200,11 +197,7 @@ function toError(e: ServiceError): errors.ErrorPolykey { if (key === 'UNKNOWN' && errorData != null) { const error: Error = JSON.parse(errorData, reviver); return new errors.ErrorPolykeyRemote(error.message, { - data: { - nodeId, - host, - port, - }, + data: JSON.parse(connInfo), cause: error, }); } else { @@ -370,9 +363,7 @@ function reviver(key: string, value: any): any { */ function promisifyUnaryCall( client: Client, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, f: (...args: any[]) => ClientUnaryCall, ): (...args: any[]) => PromiseUnaryCall { return (...args) => { @@ -384,9 +375,7 @@ function promisifyUnaryCall( const { p: pMeta, resolveP: resolveMetaP } = promise(); const callback = (error: ServiceError, ...values) => { if (error != null) { - error.metadata.set('nodeId', nodesUtils.encodeNodeId(nodeId)); - error.metadata.set('host', host); - error.metadata.set('port', port.toString()); + error.metadata.set('metadata', JSON.stringify(metadata)); rejectP(toError(error)); return; } @@ -412,22 +401,27 @@ function promisifyUnaryCall( */ function generatorReadable( stream: ClientReadableStream, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, ): AsyncGeneratorReadableStream>; function generatorReadable( stream: ServerReadableStream, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, ): AsyncGeneratorReadableStream>; function generatorReadable( stream: ClientReadableStream | ServerReadableStream, - nodeId: NodeId, - host: Host, - port: Port, + 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]; + } const gf = async function* () { try { let vR = yield; @@ -448,9 +442,7 @@ function generatorReadable( } } catch (e) { stream.destroy(); - e.metadata.set('nodeId', nodesUtils.encodeNodeId(nodeId)); - e.metadata.set('host', host); - e.metadata.set('port', port.toString()); + e.metadata.set('metadata', JSON.stringify(metadata)); throw toError(e); } }; @@ -468,9 +460,7 @@ function generatorReadable( */ function promisifyReadableStreamCall( client: grpc.Client, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, f: (...args: any[]) => ClientReadableStream, ): ( ...args: any[] @@ -483,9 +473,7 @@ function promisifyReadableStreamCall( }); const g = generatorReadable( stream, - nodeId, - host, - port, + metadata, ) as AsyncGeneratorReadableStreamClient>; g.meta = pMeta; return g; @@ -544,9 +532,7 @@ function generatorWritable( */ function promisifyWritableStreamCall( client: grpc.Client, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, f: (...args: any[]) => ClientWritableStream, ): ( ...args: any[] @@ -562,9 +548,7 @@ function promisifyWritableStreamCall( }; const callback = (error, ...values) => { if (error != null) { - error.metadata.set('nodeId', nodesUtils.encodeNodeId(nodeId)); - error.metadata.set('host', host); - error.metadata.set('port', port.toString()); + error.metadata.set('metadata', JSON.stringify(metadata)); return rejectP(toError(error)); } return resolveP(values.length === 1 ? values[0] : values); @@ -597,26 +581,20 @@ function promisifyWritableStreamCall( */ function generatorDuplex( stream: ClientDuplexStream, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ServerDuplexStream, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ClientDuplexStream | ServerDuplexStream, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, sensitive: boolean = false, ) { - const gR = generatorReadable(stream as any, nodeId, host, port); + const gR = generatorReadable(stream as any, metadata); const gW = generatorWritable(stream as any, sensitive); const gf = async function* () { let vR: any, vW: any; @@ -666,9 +644,7 @@ function generatorDuplex( */ function promisifyDuplexStreamCall( client: grpc.Client, - nodeId: NodeId, - host: Host, - port: Port, + metadata: POJO, f: (...args: any[]) => ClientDuplexStream, ): ( ...args: any[] @@ -685,9 +661,7 @@ function promisifyDuplexStreamCall( }); const g = generatorDuplex( stream, - nodeId, - host, - port, + metadata, false, ) as AsyncGeneratorDuplexStreamClient< TRead, From b611f2ed027e1c3886b0811a148a56ce2b39bb21 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Thu, 19 May 2022 17:33:34 +1000 Subject: [PATCH 41/74] feat: adding transactions to client service handlers --- src/bin/utils/utils.ts | 26 ++++++-- src/client/service/agentLockAll.ts | 7 +- .../service/gestaltsActionsGetByIdentity.ts | 3 + .../service/gestaltsActionsGetByNode.ts | 7 +- .../service/gestaltsActionsSetByIdentity.ts | 14 ++-- .../service/gestaltsActionsSetByNode.ts | 7 +- .../service/gestaltsActionsUnsetByIdentity.ts | 14 ++-- .../service/gestaltsActionsUnsetByNode.ts | 7 +- .../service/gestaltsGestaltGetByIdentity.ts | 8 ++- .../service/gestaltsGestaltGetByNode.ts | 7 +- src/client/service/gestaltsGestaltList.ts | 7 +- .../service/gestaltsGestaltTrustByIdentity.ts | 47 ++++++++------ .../service/gestaltsGestaltTrustByNode.ts | 30 +++++---- src/client/service/identitiesClaim.ts | 20 ++++-- src/client/service/identitiesTokenDelete.ts | 7 +- src/client/service/identitiesTokenGet.ts | 7 +- src/client/service/identitiesTokenPut.ts | 16 ++++- src/client/service/nodesAdd.ts | 17 +++-- src/client/service/nodesClaim.ts | 36 +++++----- src/client/service/notificationsClear.ts | 7 +- src/client/service/notificationsRead.ts | 16 +++-- src/client/service/vaultsClone.ts | 7 +- src/client/service/vaultsCreate.ts | 7 +- src/client/service/vaultsDelete.ts | 14 +++- src/client/service/vaultsList.ts | 10 +-- src/client/service/vaultsLog.ts | 28 +++++--- src/client/service/vaultsPermissionGet.ts | 19 ++++-- src/client/service/vaultsPermissionSet.ts | 60 +++++++++-------- src/client/service/vaultsPermissionUnset.ts | 65 ++++++++++--------- src/client/service/vaultsPull.ts | 53 ++++++++------- src/client/service/vaultsRename.ts | 18 +++-- src/client/service/vaultsSecretsDelete.ts | 22 +++++-- src/client/service/vaultsSecretsEdit.ts | 24 +++++-- src/client/service/vaultsSecretsGet.ts | 29 ++++++--- src/client/service/vaultsSecretsList.ts | 25 ++++--- src/client/service/vaultsSecretsMkdir.ts | 24 +++++-- src/client/service/vaultsSecretsNew.ts | 24 +++++-- src/client/service/vaultsSecretsNewDir.ts | 22 +++++-- src/client/service/vaultsSecretsRename.ts | 24 +++++-- src/client/service/vaultsSecretsStat.ts | 24 +++++-- src/client/service/vaultsVersion.ts | 44 ++++++++----- src/nodes/NodeManager.ts | 36 +++++----- tests/client/rpcVaults.test.ts | 5 ++ ...staltsActionsSetUnsetGetByIdentity.test.ts | 2 + .../gestaltsActionsSetUnsetGetByNode.test.ts | 3 + .../gestaltsGestaltGetByIdentity.test.ts | 1 + .../service/gestaltsGestaltGetByNode.test.ts | 1 + .../service/gestaltsGestaltList.test.ts | 1 + .../gestaltsGestaltTrustByIdentity.test.ts | 1 + .../gestaltsGestaltTrustByNode.test.ts | 1 + tests/client/service/identitiesClaim.test.ts | 1 + .../identitiesTokenPutDeleteGet.test.ts | 3 + tests/client/service/nodesAdd.test.ts | 1 + tests/client/service/nodesClaim.test.ts | 1 + .../client/service/notificationsClear.test.ts | 1 + .../client/service/notificationsRead.test.ts | 1 + 56 files changed, 623 insertions(+), 289 deletions(-) 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/client/service/agentLockAll.ts b/src/client/service/agentLockAll.ts index 02caef2c1..f1d4c4d03 100644 --- a/src/client/service/agentLockAll.ts +++ b/src/client/service/agentLockAll.ts @@ -1,5 +1,5 @@ -import type { DB } from '@matrixai/db'; 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'; @@ -26,9 +26,8 @@ function agentLockAll({ const response = new utilsPB.EmptyMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - await withF( - [db.transaction()], - async ([tran]) => await sessionManager.resetKey(tran), + await db.withTransactionF( + async (tran) => await sessionManager.resetKey(tran), ); callback(null, response); return; diff --git a/src/client/service/gestaltsActionsGetByIdentity.ts b/src/client/service/gestaltsActionsGetByIdentity.ts index db6faa41e..14da28205 100644 --- a/src/client/service/gestaltsActionsGetByIdentity.ts +++ b/src/client/service/gestaltsActionsGetByIdentity.ts @@ -1,5 +1,6 @@ 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/GestaltGraph'; import type { IdentityId, ProviderId } from '../../identities/types'; @@ -14,10 +15,12 @@ import * as permissionsPB from '../../proto/js/polykey/v1/permissions/permission function gestaltsActionsGetByIdentity({ authenticate, gestaltGraph, + db, logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; logger: Logger; }) { return async ( diff --git a/src/client/service/gestaltsActionsGetByNode.ts b/src/client/service/gestaltsActionsGetByNode.ts index 162b6be9f..77ad8360a 100644 --- a/src/client/service/gestaltsActionsGetByNode.ts +++ b/src/client/service/gestaltsActionsGetByNode.ts @@ -1,4 +1,5 @@ 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/GestaltGraph'; @@ -13,10 +14,12 @@ import * as permissionsPB from '../../proto/js/polykey/v1/permissions/permission function gestaltsActionsGetByNode({ authenticate, gestaltGraph, + db, logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; + db: DB; logger: Logger; }) { return async ( @@ -38,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([]); diff --git a/src/client/service/gestaltsActionsSetByIdentity.ts b/src/client/service/gestaltsActionsSetByIdentity.ts index 318ca90b6..b0975d562 100644 --- a/src/client/service/gestaltsActionsSetByIdentity.ts +++ b/src/client/service/gestaltsActionsSetByIdentity.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { GestaltAction } from '../../gestalts/types'; @@ -14,10 +15,12 @@ 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 ( @@ -51,10 +54,13 @@ 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; diff --git a/src/client/service/gestaltsActionsSetByNode.ts b/src/client/service/gestaltsActionsSetByNode.ts index cd035f0cf..917e3b198 100644 --- a/src/client/service/gestaltsActionsSetByNode.ts +++ b/src/client/service/gestaltsActionsSetByNode.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { GestaltAction } from '../../gestalts/types'; @@ -14,10 +15,12 @@ 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 ( @@ -42,7 +45,9 @@ 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) { diff --git a/src/client/service/gestaltsActionsUnsetByIdentity.ts b/src/client/service/gestaltsActionsUnsetByIdentity.ts index 8cbd2596a..cb976d117 100644 --- a/src/client/service/gestaltsActionsUnsetByIdentity.ts +++ b/src/client/service/gestaltsActionsUnsetByIdentity.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { GestaltAction } from '../../gestalts/types'; @@ -14,10 +15,12 @@ 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 ( @@ -51,10 +54,13 @@ 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; diff --git a/src/client/service/gestaltsActionsUnsetByNode.ts b/src/client/service/gestaltsActionsUnsetByNode.ts index 958a18060..2bc5d410f 100644 --- a/src/client/service/gestaltsActionsUnsetByNode.ts +++ b/src/client/service/gestaltsActionsUnsetByNode.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { GestaltAction } from '../../gestalts/types'; @@ -14,10 +15,12 @@ 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 ( @@ -42,7 +45,9 @@ 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) { diff --git a/src/client/service/gestaltsGestaltGetByIdentity.ts b/src/client/service/gestaltsGestaltGetByIdentity.ts index c303995ee..4e4a25d78 100644 --- a/src/client/service/gestaltsGestaltGetByIdentity.ts +++ b/src/client/service/gestaltsGestaltGetByIdentity.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { IdentityId, ProviderId } from '../../identities/types'; @@ -13,10 +14,12 @@ 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 ( @@ -46,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)); diff --git a/src/client/service/gestaltsGestaltGetByNode.ts b/src/client/service/gestaltsGestaltGetByNode.ts index 4cb9cf96d..28fc02c3f 100644 --- a/src/client/service/gestaltsGestaltGetByNode.ts +++ b/src/client/service/gestaltsGestaltGetByNode.ts @@ -1,4 +1,5 @@ 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/GestaltGraph'; @@ -13,10 +14,12 @@ 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 ( @@ -42,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)); } diff --git a/src/client/service/gestaltsGestaltList.ts b/src/client/service/gestaltsGestaltList.ts index 690988c20..bb96dd53a 100644 --- a/src/client/service/gestaltsGestaltList.ts +++ b/src/client/service/gestaltsGestaltList.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { Gestalt } from '../../gestalts/types'; @@ -10,10 +11,12 @@ 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 ( @@ -24,7 +27,9 @@ function gestaltsGestaltList({ 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)); diff --git a/src/client/service/gestaltsGestaltTrustByIdentity.ts b/src/client/service/gestaltsGestaltTrustByIdentity.ts index a5359bc82..71368e7fb 100644 --- a/src/client/service/gestaltsGestaltTrustByIdentity.ts +++ b/src/client/service/gestaltsGestaltTrustByIdentity.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type { IdentityId, ProviderId } from '../../identities/types'; @@ -15,11 +16,13 @@ function gestaltsGestaltTrustByIdentity({ authenticate, gestaltGraph, discovery, + db, logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; discovery: Discovery; + db: DB; logger: Logger; }) { return async ( @@ -50,25 +53,31 @@ 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) { diff --git a/src/client/service/gestaltsGestaltTrustByNode.ts b/src/client/service/gestaltsGestaltTrustByNode.ts index bad8dc219..097a94b07 100644 --- a/src/client/service/gestaltsGestaltTrustByNode.ts +++ b/src/client/service/gestaltsGestaltTrustByNode.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type Discovery from '../../discovery/Discovery'; @@ -16,11 +17,13 @@ function gestaltsGestaltTrustByNode({ authenticate, gestaltGraph, discovery, + db, logger, }: { authenticate: Authenticate; gestaltGraph: GestaltGraph; discovery: Discovery; + db: DB; logger: Logger; }) { return async ( @@ -46,17 +49,22 @@ 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) { diff --git a/src/client/service/identitiesClaim.ts b/src/client/service/identitiesClaim.ts index 93a947e42..43919bd45 100644 --- a/src/client/service/identitiesClaim.ts +++ b/src/client/service/identitiesClaim.ts @@ -1,4 +1,5 @@ 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/Sigchain'; @@ -22,12 +23,14 @@ function identitiesClaim({ identitiesManager, sigchain, keyManager, + db, logger, }: { authenticate: Authenticate; identitiesManager: IdentitiesManager; sigchain: Sigchain; keyManager: KeyManager; + db: DB; logger: Logger; }) { return async ( @@ -67,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); diff --git a/src/client/service/identitiesTokenDelete.ts b/src/client/service/identitiesTokenDelete.ts index 347e37bb4..82d0d57d5 100644 --- a/src/client/service/identitiesTokenDelete.ts +++ b/src/client/service/identitiesTokenDelete.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityId, ProviderId } from '../../identities/types'; @@ -13,10 +14,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function identitiesTokenDelete({ authenticate, identitiesManager, + db, logger, }: { authenticate: Authenticate; identitiesManager: IdentitiesManager; + db: DB; logger: Logger; }) { return async ( @@ -46,7 +49,9 @@ 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) { diff --git a/src/client/service/identitiesTokenGet.ts b/src/client/service/identitiesTokenGet.ts index 7844382a8..09199866d 100644 --- a/src/client/service/identitiesTokenGet.ts +++ b/src/client/service/identitiesTokenGet.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityId, ProviderId } from '../../identities/types'; @@ -12,10 +13,12 @@ import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_p function identitiesTokenGet({ authenticate, identitiesManager, + db, logger, }: { authenticate: Authenticate; identitiesManager: IdentitiesManager; + db: DB; logger: Logger; }) { return async ( @@ -45,7 +48,9 @@ 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; diff --git a/src/client/service/identitiesTokenPut.ts b/src/client/service/identitiesTokenPut.ts index babfd8db7..336f1646a 100644 --- a/src/client/service/identitiesTokenPut.ts +++ b/src/client/service/identitiesTokenPut.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type IdentitiesManager from '../../identities/IdentitiesManager'; import type { IdentityId, ProviderId, TokenData } from '../../identities/types'; @@ -13,10 +14,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function identitiesTokenPut({ authenticate, identitiesManager, + db, logger, }: { authenticate: Authenticate; identitiesManager: IdentitiesManager; + db: DB; logger: Logger; }) { return async ( @@ -49,9 +52,16 @@ 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) { diff --git a/src/client/service/nodesAdd.ts b/src/client/service/nodesAdd.ts index cda85ee22..1433e0896 100644 --- a/src/client/service/nodesAdd.ts +++ b/src/client/service/nodesAdd.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type NodeManager from '../../nodes/NodeManager'; import type { NodeId, NodeAddress } from '../../nodes/types'; @@ -19,10 +20,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function nodesAdd({ authenticate, nodeManager, + db, logger, }: { authenticate: Authenticate; nodeManager: NodeManager; + db: DB; logger: Logger; }) { return async ( @@ -56,10 +59,16 @@ 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) { diff --git a/src/client/service/nodesClaim.ts b/src/client/service/nodesClaim.ts index 3c165d579..4d9cdc783 100644 --- a/src/client/service/nodesClaim.ts +++ b/src/client/service/nodesClaim.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type NodeManager from '../../nodes/NodeManager'; import type { NodeId } from '../../nodes/types'; @@ -20,11 +21,13 @@ function nodesClaim({ authenticate, nodeManager, notificationsManager, + db, logger, }: { authenticate: Authenticate; nodeManager: NodeManager; notificationsManager: NotificationsManager; + db: DB; logger: Logger; }) { return async ( @@ -50,21 +53,24 @@ 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) { diff --git a/src/client/service/notificationsClear.ts b/src/client/service/notificationsClear.ts index 2fd077c9b..56b2fabef 100644 --- a/src/client/service/notificationsClear.ts +++ b/src/client/service/notificationsClear.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type NotificationsManager from '../../notifications/NotificationsManager'; import type Logger from '@matrixai/logger'; @@ -8,10 +9,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function notificationsClear({ authenticate, notificationsManager, + db, logger, }: { authenticate: Authenticate; notificationsManager: NotificationsManager; + db: DB; logger: Logger; }) { return async ( @@ -22,7 +25,9 @@ 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) { diff --git a/src/client/service/notificationsRead.ts b/src/client/service/notificationsRead.ts index 630940764..63b94438d 100644 --- a/src/client/service/notificationsRead.ts +++ b/src/client/service/notificationsRead.ts @@ -1,4 +1,5 @@ import type * as grpc from '@grpc/grpc-js'; +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type NotificationsManager from '../../notifications/NotificationsManager'; import type Logger from '@matrixai/logger'; @@ -8,10 +9,12 @@ import * as notificationsPB from '../../proto/js/polykey/v1/notifications/notifi function notificationsRead({ authenticate, notificationsManager, + db, logger, }: { authenticate: Authenticate; notificationsManager: NotificationsManager; + db: DB; logger: Logger; }) { return async ( @@ -31,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(); diff --git a/src/client/service/vaultsClone.ts b/src/client/service/vaultsClone.ts index 75b6dcf56..bd3693c5c 100644 --- a/src/client/service/vaultsClone.ts +++ b/src/client/service/vaultsClone.ts @@ -1,3 +1,4 @@ +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'; @@ -11,10 +12,12 @@ import * as vaultsUtils from '../../vaults/utils'; function vaultsClone({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -43,7 +46,9 @@ 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; diff --git a/src/client/service/vaultsCreate.ts b/src/client/service/vaultsCreate.ts index 74224733b..a739604e7 100644 --- a/src/client/service/vaultsCreate.ts +++ b/src/client/service/vaultsCreate.ts @@ -2,6 +2,7 @@ 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'; @@ -11,10 +12,12 @@ import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsCreate({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -26,8 +29,8 @@ 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); diff --git a/src/client/service/vaultsDelete.ts b/src/client/service/vaultsDelete.ts index 0f7aa01e7..7a87f2da0 100644 --- a/src/client/service/vaultsDelete.ts +++ b/src/client/service/vaultsDelete.ts @@ -2,6 +2,7 @@ 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'; @@ -11,10 +12,12 @@ import * as validationUtils from '../../validation/utils'; function vaultsDelete({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -27,9 +30,14 @@ 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; diff --git a/src/client/service/vaultsList.ts b/src/client/service/vaultsList.ts index 794c44909..a4a618275 100644 --- a/src/client/service/vaultsList.ts +++ b/src/client/service/vaultsList.ts @@ -1,6 +1,7 @@ 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'; @@ -10,23 +11,24 @@ import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsList({ authenticate, vaultManager, + db, logger, }: { 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, 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); diff --git a/src/client/service/vaultsLog.ts b/src/client/service/vaultsLog.ts index 6d720e825..367dd0a1e 100644 --- a/src/client/service/vaultsLog.ts +++ b/src/client/service/vaultsLog.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'; @@ -11,10 +12,12 @@ import * as validationUtils from '../../validation/utils'; function vaultsLog({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -32,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) { diff --git a/src/client/service/vaultsPermissionGet.ts b/src/client/service/vaultsPermissionGet.ts index 1682044ad..8e62be35a 100644 --- a/src/client/service/vaultsPermissionGet.ts +++ b/src/client/service/vaultsPermissionGet.ts @@ -1,4 +1,5 @@ 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'; @@ -17,11 +18,13 @@ function vaultsPermissionGet({ authenticate, vaultManager, acl, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; acl: ACL; + db: DB; logger: Logger; }) { return async ( @@ -34,11 +37,17 @@ function vaultsPermissionGet({ 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) { diff --git a/src/client/service/vaultsPermissionSet.ts b/src/client/service/vaultsPermissionSet.ts index f19ec7da3..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'; @@ -20,6 +21,7 @@ function vaultsPermissionSet({ gestaltGraph, acl, notificationsManager, + db, logger, }: { authenticate: Authenticate; @@ -27,6 +29,7 @@ function vaultsPermissionSet({ gestaltGraph: GestaltGraph; acl: ACL; notificationsManager: NotificationsManager; + db: DB; logger: Logger; }) { return async ( @@ -44,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); diff --git a/src/client/service/vaultsPermissionUnset.ts b/src/client/service/vaultsPermissionUnset.ts index cd9c0ee9e..8095e21c4 100644 --- a/src/client/service/vaultsPermissionUnset.ts +++ b/src/client/service/vaultsPermissionUnset.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'; @@ -16,12 +17,14 @@ function vaultsPermissionUnset({ vaultManager, gestaltGraph, acl, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; gestaltGraph: GestaltGraph; acl: ACL; + db: DB; logger: Logger; }) { return async ( @@ -39,37 +42,39 @@ 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); diff --git a/src/client/service/vaultsPull.ts b/src/client/service/vaultsPull.ts index 821e3179a..f68a62903 100644 --- a/src/client/service/vaultsPull.ts +++ b/src/client/service/vaultsPull.ts @@ -1,3 +1,4 @@ +import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; import type { VaultName } from '../../vaults/types'; @@ -12,10 +13,12 @@ import * as vaultsUtils from '../../vaults/utils'; function vaultsPull({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -33,28 +36,34 @@ 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); diff --git a/src/client/service/vaultsRename.ts b/src/client/service/vaultsRename.ts index 27276c1aa..0689b2506 100644 --- a/src/client/service/vaultsRename.ts +++ b/src/client/service/vaultsRename.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'; @@ -11,10 +12,12 @@ import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsRename({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -31,11 +34,16 @@ 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) { diff --git a/src/client/service/vaultsSecretsDelete.ts b/src/client/service/vaultsSecretsDelete.ts index 6332c1442..46784f9fe 100644 --- a/src/client/service/vaultsSecretsDelete.ts +++ b/src/client/service/vaultsSecretsDelete.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'; @@ -12,10 +13,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsDelete({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -32,11 +35,20 @@ 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); diff --git a/src/client/service/vaultsSecretsEdit.ts b/src/client/service/vaultsSecretsEdit.ts index d502d9808..897a6dd12 100644 --- a/src/client/service/vaultsSecretsEdit.ts +++ b/src/client/service/vaultsSecretsEdit.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'; @@ -12,10 +13,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsEdit({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -37,12 +40,21 @@ 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); diff --git a/src/client/service/vaultsSecretsGet.ts b/src/client/service/vaultsSecretsGet.ts index bd3c3a330..cdb2a75fb 100644 --- a/src/client/service/vaultsSecretsGet.ts +++ b/src/client/service/vaultsSecretsGet.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'; @@ -12,10 +13,12 @@ import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; function vaultsSecretsGet({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -32,16 +35,22 @@ 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) { diff --git a/src/client/service/vaultsSecretsList.ts b/src/client/service/vaultsSecretsList.ts index c9732edbf..8056c7a90 100644 --- a/src/client/service/vaultsSecretsList.ts +++ b/src/client/service/vaultsSecretsList.ts @@ -2,6 +2,7 @@ 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'; @@ -12,10 +13,12 @@ import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; function vaultsSecretsList({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -27,14 +30,20 @@ function vaultsSecretsList({ 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(); diff --git a/src/client/service/vaultsSecretsMkdir.ts b/src/client/service/vaultsSecretsMkdir.ts index 3753571c7..6d5649fb5 100644 --- a/src/client/service/vaultsSecretsMkdir.ts +++ b/src/client/service/vaultsSecretsMkdir.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'; @@ -12,10 +13,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsMkdir({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -33,12 +36,21 @@ 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); diff --git a/src/client/service/vaultsSecretsNew.ts b/src/client/service/vaultsSecretsNew.ts index b264631f9..0a6c1920c 100644 --- a/src/client/service/vaultsSecretsNew.ts +++ b/src/client/service/vaultsSecretsNew.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'; @@ -12,10 +13,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsNew({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -32,12 +35,21 @@ 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); diff --git a/src/client/service/vaultsSecretsNewDir.ts b/src/client/service/vaultsSecretsNewDir.ts index 36fd2b3af..daf151f58 100644 --- a/src/client/service/vaultsSecretsNewDir.ts +++ b/src/client/service/vaultsSecretsNewDir.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'; @@ -14,11 +15,13 @@ function vaultsSecretsNewDir({ authenticate, vaultManager, fs, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; fs: FileSystem; + db: DB; logger: Logger; }) { return async ( @@ -35,11 +38,20 @@ 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); diff --git a/src/client/service/vaultsSecretsRename.ts b/src/client/service/vaultsSecretsRename.ts index ceeb7160e..fabe0512c 100644 --- a/src/client/service/vaultsSecretsRename.ts +++ b/src/client/service/vaultsSecretsRename.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'; @@ -12,10 +13,12 @@ import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; function vaultsSecretsRename({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -37,12 +40,21 @@ 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); diff --git a/src/client/service/vaultsSecretsStat.ts b/src/client/service/vaultsSecretsStat.ts index ab03c57e4..d30b1e20f 100644 --- a/src/client/service/vaultsSecretsStat.ts +++ b/src/client/service/vaultsSecretsStat.ts @@ -1,3 +1,4 @@ +import type { DB } from '@matrixai/db'; import type VaultManager from '../../vaults/VaultManager'; import type { VaultName } from '../../vaults/types'; import type { Authenticate } from '../types'; @@ -11,10 +12,12 @@ 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 ( @@ -31,13 +34,22 @@ 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) { diff --git a/src/client/service/vaultsVersion.ts b/src/client/service/vaultsVersion.ts index fcb32a2fe..18868456b 100644 --- a/src/client/service/vaultsVersion.ts +++ b/src/client/service/vaultsVersion.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'; @@ -10,10 +11,12 @@ import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; function vaultsVersion({ authenticate, vaultManager, + db, logger, }: { authenticate: Authenticate; vaultManager: VaultManager; + db: DB; logger: Logger; }) { return async ( @@ -33,23 +36,30 @@ 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; diff --git a/src/nodes/NodeManager.ts b/src/nodes/NodeManager.ts index fe57b8001..6adf77867 100644 --- a/src/nodes/NodeManager.ts +++ b/src/nodes/NodeManager.ts @@ -306,13 +306,14 @@ class NodeManager { /** * 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 { - // FIXME: use tran - return await this.nodeGraph.getNode(nodeId); + return await this.nodeGraph.getNode(nodeId, tran); } /** @@ -331,9 +332,11 @@ class NodeManager { /** * Gets the specified bucket from the NodeGraph */ - public async getBucket(bucketIndex: number): Promise { - // FIXME: use tran - return await this.nodeGraph.getBucket(bucketIndex); + public async getBucket( + bucketIndex: number, + tran?: DBTransaction, + ): Promise { + return await this.nodeGraph.getBucket(bucketIndex, tran); } /** @@ -342,9 +345,9 @@ class NodeManager { public async setNode( nodeId: NodeId, nodeAddress: NodeAddress, + tran?: DBTransaction, ): Promise { - // FIXME: use tran - return await this.nodeGraph.setNode(nodeId, nodeAddress); + return await this.nodeGraph.setNode(nodeId, nodeAddress, tran); } /** @@ -353,34 +356,31 @@ class NodeManager { public async updateNode( nodeId: NodeId, nodeAddress?: NodeAddress, + tran?: DBTransaction, ): Promise { - // FIXME: use tran - 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 { - // FIXME: use tran - 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> { - // FIXME: use tran - 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 { - // FIXME: use tran - return await this.nodeGraph.refreshBuckets(); + public async refreshBuckets(tran?: DBTransaction): Promise { + return await this.nodeGraph.refreshBuckets(tran); } } diff --git a/tests/client/rpcVaults.test.ts b/tests/client/rpcVaults.test.ts index 8645e989f..98f4b80af 100644 --- a/tests/client/rpcVaults.test.ts +++ b/tests/client/rpcVaults.test.ts @@ -3,6 +3,7 @@ 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'; @@ -39,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; @@ -115,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) { diff --git a/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts b/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts index 09dfaae3b..f20373610 100644 --- a/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts +++ b/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts @@ -73,6 +73,7 @@ describe('gestaltsActionsByIdentity', () => { authenticate, gestaltGraph, logger, + db, }), gestaltsActionsGetByIdentity: gestaltsActionsGetByIdentity({ authenticate, @@ -83,6 +84,7 @@ describe('gestaltsActionsByIdentity', () => { 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 cfec8dfda..439f9b754 100644 --- a/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts +++ b/tests/client/service/gestaltsActionsSetUnsetGetByNode.test.ts @@ -67,16 +67,19 @@ describe('gestaltsActionsByNode', () => { 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/gestaltsGestaltGetByIdentity.test.ts b/tests/client/service/gestaltsGestaltGetByIdentity.test.ts index cddc5af3f..b6ecc2d71 100644 --- a/tests/client/service/gestaltsGestaltGetByIdentity.test.ts +++ b/tests/client/service/gestaltsGestaltGetByIdentity.test.ts @@ -90,6 +90,7 @@ describe('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 2a5848203..1d7a3ceb6 100644 --- a/tests/client/service/gestaltsGestaltGetByNode.test.ts +++ b/tests/client/service/gestaltsGestaltGetByNode.test.ts @@ -87,6 +87,7 @@ describe('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 c724124d7..1075a34f8 100644 --- a/tests/client/service/gestaltsGestaltList.test.ts +++ b/tests/client/service/gestaltsGestaltList.test.ts @@ -93,6 +93,7 @@ describe('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 ba706add1..ec38cc41d 100644 --- a/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts +++ b/tests/client/service/gestaltsGestaltTrustByIdentity.test.ts @@ -227,6 +227,7 @@ describe('gestaltsGestaltTrustByIdentity', () => { gestaltGraph, discovery, logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/gestaltsGestaltTrustByNode.test.ts b/tests/client/service/gestaltsGestaltTrustByNode.test.ts index 7cb297e67..1c1ad87b0 100644 --- a/tests/client/service/gestaltsGestaltTrustByNode.test.ts +++ b/tests/client/service/gestaltsGestaltTrustByNode.test.ts @@ -226,6 +226,7 @@ describe('gestaltsGestaltTrustByNode', () => { gestaltGraph, discovery, logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/identitiesClaim.test.ts b/tests/client/service/identitiesClaim.test.ts index 70185582a..39535394a 100644 --- a/tests/client/service/identitiesClaim.test.ts +++ b/tests/client/service/identitiesClaim.test.ts @@ -150,6 +150,7 @@ describe('identitiesClaim', () => { sigchain, keyManager, logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/identitiesTokenPutDeleteGet.test.ts b/tests/client/service/identitiesTokenPutDeleteGet.test.ts index f26eb192b..1752e2f94 100644 --- a/tests/client/service/identitiesTokenPutDeleteGet.test.ts +++ b/tests/client/service/identitiesTokenPutDeleteGet.test.ts @@ -57,16 +57,19 @@ describe('identitiesTokenPutDeleteGet', () => { 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/nodesAdd.test.ts b/tests/client/service/nodesAdd.test.ts index aaff85bc3..86923b961 100644 --- a/tests/client/service/nodesAdd.test.ts +++ b/tests/client/service/nodesAdd.test.ts @@ -118,6 +118,7 @@ describe('nodesAdd', () => { authenticate, nodeManager, logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/nodesClaim.test.ts b/tests/client/service/nodesClaim.test.ts index bcecd0741..bee8c8ad3 100644 --- a/tests/client/service/nodesClaim.test.ts +++ b/tests/client/service/nodesClaim.test.ts @@ -161,6 +161,7 @@ describe('nodesClaim', () => { nodeManager, notificationsManager, logger, + db, }), }; grpcServer = new GRPCServer({ logger }); diff --git a/tests/client/service/notificationsClear.test.ts b/tests/client/service/notificationsClear.test.ts index 62cc7ce63..d8572c584 100644 --- a/tests/client/service/notificationsClear.test.ts +++ b/tests/client/service/notificationsClear.test.ts @@ -136,6 +136,7 @@ describe('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 393943f5e..73690a54d 100644 --- a/tests/client/service/notificationsRead.test.ts +++ b/tests/client/service/notificationsRead.test.ts @@ -210,6 +210,7 @@ describe('notificationsRead', () => { authenticate, notificationsManager, logger, + db, }), }; grpcServer = new GRPCServer({ logger }); From fcbf66bb88dcba6f8fd2273897feb455355b1f5b Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 20 May 2022 10:15:20 +1000 Subject: [PATCH 42/74] feat: NodeId in ErrorPolykeyRemote data now encoded --- src/grpc/utils/utils.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/grpc/utils/utils.ts b/src/grpc/utils/utils.ts index 4b7335fd5..f99331585 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -35,6 +35,7 @@ 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'; /** @@ -375,6 +376,9 @@ 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; @@ -422,6 +426,9 @@ function generatorReadable( 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; @@ -548,6 +555,9 @@ 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)); } From 734662bfc2ae5c70e4621b05f38fb5e1e7fb7eab Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Fri, 20 May 2022 16:08:10 +1000 Subject: [PATCH 43/74] feat: updated `NodeConnectionManager`'s resourceAcquire to handle errors properly Making use of the updated API to use the error provided to the resourceRelease. --- src/nodes/NodeConnectionManager.ts | 65 +++++++++++++----------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/nodes/NodeConnectionManager.ts b/src/nodes/NodeConnectionManager.ts index 812b18832..9f7632d2f 100644 --- a/src/nodes/NodeConnectionManager.ts +++ b/src/nodes/NodeConnectionManager.ts @@ -138,8 +138,16 @@ class NodeConnectionManager { connAndLock.timer?.refresh(); // Return tuple of [ResourceRelease, Resource] return [ - async () => { + 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, ]; @@ -159,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); + }, + ); } /** @@ -201,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 } @@ -310,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]; @@ -507,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(); } From b118a9579096683c6375c73c41b0066f90686c97 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Fri, 20 May 2022 18:39:23 +1000 Subject: [PATCH 44/74] feat: updated `NodeConnectionManager` to use `LockBox` for object map locking Using `LockBox` allowed us to greatly simplify using the object map and creating connections. --- src/nodes/NodeConnectionManager.ts | 246 +++++++----------- .../NodeConnectionManager.lifecycle.test.ts | 167 +++++------- .../NodeConnectionManager.termination.test.ts | 60 +++-- .../NodeConnectionManager.timeout.test.ts | 32 +-- 4 files changed, 218 insertions(+), 287 deletions(-) diff --git a/src/nodes/NodeConnectionManager.ts b/src/nodes/NodeConnectionManager.ts index 9f7632d2f..e51ccc803 100644 --- a/src/nodes/NodeConnectionManager.ts +++ b/src/nodes/NodeConnectionManager.ts @@ -5,19 +5,19 @@ import type { Host, Hostname, Port } from '../network/types'; import type { Timer } from '../types'; import type NodeGraph from './NodeGraph'; import type { - NodeId, NodeAddress, NodeData, - SeedNodes, + NodeId, NodeIdString, + SeedNodes, } from './types'; import type { DBTransaction } from '@matrixai/db'; +import { withF } from '@matrixai/resources'; import Logger from '@matrixai/logger'; -import { StartStop, ready } from '@matrixai/async-init/dist/StartStop'; +import { ready, StartStop } 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 { LockBox, RWLockWriter } from '@matrixai/async-locks'; import NodeConnection from './NodeConnection'; import * as nodesUtils from './utils'; import * as nodesErrors from './errors'; @@ -28,17 +28,16 @@ import * as agentErrors from '../agent/errors'; import * as grpcErrors from '../grpc/errors'; import * as nodesPB from '../proto/js/polykey/v1/nodes/nodes_pb'; -type ConnectionAndLock = { - connection?: NodeConnection; - timer?: NodeJS.Timer; - lock: RWLockWriter; +type ConnectionAndTimer = { + connection: NodeConnection; + timer: NodeJS.Timer; }; interface NodeConnectionManager extends StartStop {} @StartStop() class NodeConnectionManager { /** - * Time used to estalish `NodeConnection` + * Time used to establish `NodeConnection` */ public readonly connConnectTime: number; @@ -48,7 +47,7 @@ class NodeConnectionManager { public readonly connTimeoutTime: number; /** * Alpha constant for kademlia - * The number of closest nodes to contact initially + * The number of the closest nodes to contact initially */ public readonly initialClosestNodes: number; @@ -67,7 +66,8 @@ class NodeConnectionManager { * A nodeIdString is used for the key here since * NodeIds can't be used to properly retrieve a value from the map. */ - protected connections: Map = new Map(); + protected connections: Map = new Map(); + protected connectionLocks: LockBox = new LockBox(); public constructor({ keyManager, @@ -119,7 +119,7 @@ class NodeConnectionManager { } /** - * For usage with withF, to acquire a connection in a + * For usage with withF, to acquire a connection * This unique acquire function structure of returning the ResourceAcquire * itself is such that we can pass targetNodeId as a parameter (as opposed to * an acquire function with no parameters). @@ -131,11 +131,15 @@ class NodeConnectionManager { targetNodeId: NodeId, ): Promise>> { return async () => { - const connAndLock = await this.getConnection(targetNodeId); + const { connection, timer } = await this.getConnection(targetNodeId); // Acquire the read lock and the release function - const [release] = await connAndLock.lock.read()(); + const [release] = await this.connectionLocks.lock([ + targetNodeId.toString(), + RWLockWriter, + 'write', + ])(); // Resetting TTL timer - connAndLock.timer?.refresh(); + timer?.refresh(); // Return tuple of [ResourceRelease, Resource] return [ async (e) => { @@ -149,7 +153,7 @@ class NodeConnectionManager { await this.destroyConnection(targetNodeId); } }, - connAndLock.connection, + connection, ]; }; } @@ -213,127 +217,82 @@ class NodeConnectionManager { * Create a connection to another node (without performing any function). * This is a NOOP if a connection already exists. * @param targetNodeId Id of node we are creating connection to - * @returns ConnectionAndLock that was create or exists in the connection map. + * @returns ConnectionAndLock that was created or exists in the connection map. */ protected async getConnection( targetNodeId: NodeId, - ): Promise { + ): Promise { this.logger.info( `Getting connection to ${nodesUtils.encodeNodeId(targetNodeId)}`, ); - let connection: NodeConnection | undefined; - let lock: RWLockWriter; - let connAndLock = this.connections.get( - targetNodeId.toString() as NodeIdString, - ); - if (connAndLock != null) { - ({ connection, lock } = connAndLock); - // Connection already exists, so return - if (connection != null) return connAndLock; - // Acquire the write (creation) lock - return await lock.withWriteF(async () => { - // Once lock is released, check again if the conn now exists - connAndLock = this.connections.get( - targetNodeId.toString() as NodeIdString, - ); - if (connAndLock != null && connAndLock.connection != null) { + const targetNodeIdString = targetNodeId.toString() as NodeIdString; + return await this.connectionLocks.withF( + [targetNodeIdString, RWLockWriter, 'write'], + async () => { + const connAndTimer = this.connections.get(targetNodeIdString); + if (connAndTimer != null) { this.logger.info( `existing entry found for ${nodesUtils.encodeNodeId(targetNodeId)}`, ); - return connAndLock; + return connAndTimer; } - this.logger.info( - `existing lock, creating connection to ${nodesUtils.encodeNodeId( - targetNodeId, - )}`, - ); - // Creating the connection and set in map - return await this.establishNodeConnection(targetNodeId, lock); - }); - } else { - lock = new RWLockWriter(); - connAndLock = { lock }; - this.connections.set( - targetNodeId.toString() as NodeIdString, - connAndLock, - ); - return await lock.withWriteF(async () => { this.logger.info( `no existing entry, creating connection to ${nodesUtils.encodeNodeId( targetNodeId, )}`, ); // Creating the connection and set in map - return await this.establishNodeConnection(targetNodeId, lock); - }); - } - } + const targetAddress = await this.findNode(targetNodeId); + // If the stored host is not a valid host (IP address), + // then we assume it to be a hostname + const targetHostname = !networkUtils.isHost(targetAddress.host) + ? (targetAddress.host as string as Hostname) + : undefined; + const targetHost = await networkUtils.resolveHost(targetAddress.host); + // Creating the destroyCallback + const destroyCallback = async () => { + // To avoid deadlock only in the case where this is called + // we want to check for destroying connection and read lock + const connAndTimer = this.connections.get(targetNodeIdString); + // If the connection is calling destroyCallback then it SHOULD + // exist in the connection map + if (connAndTimer == null) return; + // Already locked so already destroying + if (this.connectionLocks.isLocked(targetNodeIdString)) return; + // Connection is already destroying + if (connAndTimer?.connection?.[status] === 'destroying') return; + await this.destroyConnection(targetNodeId); + }; + // Creating new connection + const newConnection = await NodeConnection.createNodeConnection({ + targetNodeId: targetNodeId, + targetHost: targetHost, + targetHostname: targetHostname, + targetPort: targetAddress.port, + proxy: this.proxy, + keyManager: this.keyManager, + nodeConnectionManager: this, + destroyCallback, + connConnectTime: this.connConnectTime, + logger: this.logger.getChild( + `${NodeConnection.name} ${targetHost}:${targetAddress.port}`, + ), + clientFactory: async (args) => + GRPCClientAgent.createGRPCClientAgent(args), + }); + // Creating TTL timeout + const timer = setTimeout(async () => { + await this.destroyConnection(targetNodeId); + }, this.connTimeoutTime); - /** - * Strictly a helper function for this.createConnection. Do not call this - * function anywhere else. - * To create a connection to a node, always use createConnection, or - * withConnection. - * This only adds the connection to the connection map if the connection was established. - * @param targetNodeId Id of node we are establishing connection to - * @param lock Lock associated with connection - * @returns ConnectionAndLock that was added to the connection map - */ - protected async establishNodeConnection( - targetNodeId: NodeId, - 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 - // be a hostname - const targetHostname = !networkUtils.isHost(targetAddress.host) - ? (targetAddress.host as string as Hostname) - : undefined; - const targetHost = await networkUtils.resolveHost(targetAddress.host); - // Creating the destroyCallback - const destroyCallback = async () => { - // To avoid deadlock only in the case where this is called - // we want to check for destroying connection and read lock - const connAndLock = this.connections.get( - targetNodeId.toString() as NodeIdString, - ); - // If the connection is calling destroyCallback then it SHOULD - // exist in the connection map - 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]; - // Connection is already destroying - if (connectionStatus === 'destroying') return; - await this.destroyConnection(targetNodeId); - }; - const connection = await NodeConnection.createNodeConnection({ - targetNodeId: targetNodeId, - targetHost: targetHost, - targetHostname: targetHostname, - targetPort: targetAddress.port, - proxy: this.proxy, - keyManager: this.keyManager, - nodeConnectionManager: this, - destroyCallback, - connConnectTime: this.connConnectTime, - logger: this.logger.getChild( - `${NodeConnection.name} ${targetHost}:${targetAddress.port}`, - ), - clientFactory: async (args) => - GRPCClientAgent.createGRPCClientAgent(args), - }); - // Creating TTL timeout - const timer = setTimeout(async () => { - await this.destroyConnection(targetNodeId); - }, this.connTimeoutTime); - // Add it to the map of active connections - const connectionAndLock = { connection, lock, timer }; - this.connections.set( - targetNodeId.toString() as NodeIdString, - connectionAndLock, + const newConnAndTimer: ConnectionAndTimer = { + connection: newConnection, + timer: timer, + }; + this.connections.set(targetNodeIdString, newConnAndTimer); + return newConnAndTimer; + }, ); - return connectionAndLock; } /** @@ -341,23 +300,19 @@ class NodeConnectionManager { * @param targetNodeId Id of node we are destroying connection to */ protected async destroyConnection(targetNodeId: NodeId): Promise { - const connAndLock = this.connections.get( - targetNodeId.toString() as NodeIdString, + const targetNodeIdString = targetNodeId.toString() as NodeIdString; + return await this.connectionLocks.withF( + [targetNodeIdString, RWLockWriter, 'write'], + async () => { + const connAndTimer = this.connections.get(targetNodeIdString); + if (connAndTimer?.connection == null) return; + await connAndTimer.connection.destroy(); + // Destroying TTL timer + if (connAndTimer.timer != null) clearTimeout(connAndTimer.timer); + // Updating the connection map + this.connections.delete(targetNodeIdString); + }, ); - if (connAndLock == null) return; - const connection = connAndLock.connection; - if (connection == null) return; - const lock = connAndLock.lock; - - // If the connection exists then we lock, destroy and remove it from the map - await lock.withWriteF(async () => { - // Destroying connection - await connection.destroy(); - // Destroying TTL timer - if (connAndLock.timer != null) clearTimeout(connAndLock.timer); - // Updating the connection map - this.connections.set(targetNodeId.toString() as NodeIdString, { lock }); - }); } /** @@ -389,7 +344,7 @@ class NodeConnectionManager { * sends hole-punching packets back to the server's reverse proxy. * This is not needed to be called when doing hole punching since the * ForwardProxy automatically starts the process. - * @param nodeId Node Id of the node we are connecting to + * @param nodeId Node ID of the node we are connecting to * @param proxyHost Proxy host of the reverse proxy * @param proxyPort Proxy port of the reverse proxy * @param timer Connection timeout timer @@ -429,14 +384,14 @@ class NodeConnectionManager { /** * Finds the set of nodes (of size k) known by the current node (i.e. in its - * buckets database) that have the smallest distance to the target node (i.e. + * bucket's database) that have the smallest distance to the target node (i.e. * are closest to the target node). * i.e. FIND_NODE RPC from Kademlia spec * * Used by the RPC service. * * @param targetNodeId the node ID to find other nodes closest to it - * @param numClosest the number of closest nodes to return (by default, returns + * @param numClosest the number of the 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 @@ -451,7 +406,7 @@ class NodeConnectionManager { ): Promise> { // Retrieve all nodes from buckets in database const buckets = await this.nodeGraph.getAllBuckets(tran); - // Iterate over all of the nodes in each bucket + // Iterate over all the nodes in each bucket const distanceToNodes: Array = []; buckets.forEach(function (bucket) { for (const nodeIdString of Object.keys(bucket)) { @@ -505,7 +460,7 @@ class NodeConnectionManager { // in nodeConnections - what if there's been more than 1 invocation of // getClosestGlobalNodes()? const contacted: { [nodeId: string]: boolean } = {}; - // Iterate until we've found found and contacted k nodes + // Iterate until we've found and contacted k nodes while (Object.keys(contacted).length <= this.nodeGraph.maxNodesPerBucket) { // While (!foundTarget) { // Remove the node from the front of the array @@ -553,7 +508,7 @@ class NodeConnectionManager { } // To make the number of jumps relatively short, should connect to the nodes // closest to the target first, and ask if they know of any closer nodes - // Then we can simply unshift the first (closest) element from the shortlist + // than we can simply unshift the first (closest) element from the shortlist shortlist.sort(function (a: NodeData, b: NodeData) { if (a.distance > b.distance) { return 1; @@ -607,7 +562,7 @@ class NodeConnectionManager { } /** - * Perform an initial database synchronisation: get the k closest nodes + * Perform an initial database synchronisation: get k of the closest nodes * from each seed node and add them to this database * For now, we also attempt to establish a connection to each of them. * If these nodes are offline, this will impose a performance penalty, @@ -646,7 +601,7 @@ class NodeConnectionManager { * @param relayNodeId node ID of the relay node (i.e. the seed node) * @param sourceNodeId node ID of the current node (i.e. the sender) * @param targetNodeId node ID of the target node to hole punch - * @param proxyAddress stringified address of `proxyHost:proxyPort` + * @param proxyAddress string of address in the form `proxyHost:proxyPort` * @param signature signature to verify source node is sender (signature based * on proxyAddress as message) */ @@ -693,10 +648,9 @@ class NodeConnectionManager { */ @ready(new nodesErrors.ErrorNodeConnectionManagerNotRunning()) public getSeedNodes(): Array { - const nodeIds = Object.keys(this.seedNodes).map( + return Object.keys(this.seedNodes).map( (nodeIdEncoded) => nodesUtils.decodeNodeId(nodeIdEncoded)!, ); - return nodeIds; } } diff --git a/tests/nodes/NodeConnectionManager.lifecycle.test.ts b/tests/nodes/NodeConnectionManager.lifecycle.test.ts index 66961ca1a..6117ddc41 100644 --- a/tests/nodes/NodeConnectionManager.lifecycle.test.ts +++ b/tests/nodes/NodeConnectionManager.lifecycle.test.ts @@ -78,6 +78,7 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { let remoteNode1: PolykeyAgent; let remoteNode2: PolykeyAgent; let remoteNodeId1: NodeId; + let remoteNodeIdString1: NodeIdString; let remoteNodeId2: NodeId; const mockedGenerateDeterministicKeyPair = jest.spyOn( @@ -103,6 +104,7 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { logger: logger.getChild('remoteNode1'), }); remoteNodeId1 = remoteNode1.keyManager.getNodeId(); + remoteNodeIdString1 = remoteNodeId1.toString() as NodeIdString; remoteNode2 = await PolykeyAgent.createPolykeyAgent({ password, nodePath: path.join(dataDir2, 'remoteNode2'), @@ -197,17 +199,15 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { await nodeConnectionManager.start(); // @ts-ignore: kidnap connections const connections = nodeConnectionManager.connections; - const initialConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(initialConnLock).toBeUndefined(); + // @ts-ignore: kidnap connectionLocks + const connectionLocks = nodeConnectionManager.connectionLocks; + const initialConnection = connections.get(remoteNodeIdString1); + expect(initialConnection).toBeUndefined(); await nodeConnectionManager.withConnF(remoteNodeId1, nop); - const finalConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); + const finalConnection = connections.get(remoteNodeIdString1); // Check entry is in map and lock is released - expect(finalConnLock).toBeDefined(); - expect(finalConnLock?.lock.isLocked()).toBeFalsy(); + expect(finalConnection).toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBeFalsy(); } finally { await nodeConnectionManager?.stop(); } @@ -224,32 +224,23 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { await nodeConnectionManager.start(); // @ts-ignore: kidnap connections const connections = nodeConnectionManager.connections; - const initialConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(initialConnLock).toBeUndefined(); + // @ts-ignore: kidnap connectionLocks + const connectionLocks = nodeConnectionManager.connectionLocks; + const initialConnection = connections.get(remoteNodeIdString1); + expect(initialConnection).toBeUndefined(); await withF( [await nodeConnectionManager.acquireConnection(remoteNodeId1)], async (conn) => { expect(conn).toBeDefined(); - const intermediaryConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(intermediaryConnLock).toBeDefined(); - expect( - // @ts-ignore get the protected readersLock - intermediaryConnLock?.lock.readersLock.isLocked(), - ).toBeTruthy(); - // @ts-ignore get the protected writersLock - expect(intermediaryConnLock?.lock.writersLock.isLocked()).toBeFalsy(); + const intermediaryConnection = connections.get(remoteNodeIdString1); + expect(intermediaryConnection).toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBeTruthy(); }, ); - const finalConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(finalConnLock).toBeDefined(); + const finalConnection = connections.get(remoteNodeIdString1); + expect(finalConnection).toBeDefined(); // Neither write nor read lock should be locked now - expect(finalConnLock?.lock.isLocked()).toBeFalsy(); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBeFalsy(); } finally { await nodeConnectionManager?.stop(); } @@ -267,23 +258,17 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { await nodeConnectionManager.start(); // @ts-ignore: kidnap connections const connections = nodeConnectionManager.connections; - const initialConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(initialConnLock).toBeUndefined(); + // @ts-ignore: kidnap connectionLocks + const connectionLocks = nodeConnectionManager.connectionLocks; + const initialConnection = connections.get(remoteNodeIdString1); + expect(initialConnection).toBeUndefined(); await nodeConnectionManager.withConnF(remoteNodeId1, async () => { - expect( - connections - .get(remoteNodeId1.toString() as NodeIdString) - ?.lock?.isLocked(), - ).toBe(true); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBe(true); }); - const finalConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); + const finalConnection = connections.get(remoteNodeIdString1); // Check entry is in map and lock is released - expect(finalConnLock).toBeDefined(); - expect(finalConnLock?.lock.isLocked()).toBeFalsy(); + expect(finalConnection).toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBeFalsy(); } finally { await nodeConnectionManager?.stop(); } @@ -302,10 +287,10 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { // @ts-ignore: kidnap connections const connections = nodeConnectionManager.connections; - const initialConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(initialConnLock).toBeUndefined(); + // @ts-ignore: kidnap connectionLocks + const connectionLocks = nodeConnectionManager.connectionLocks; + const initialConnection = connections.get(remoteNodeIdString1); + expect(initialConnection).toBeUndefined(); const testGenerator = async function* () { for (let i = 0; i < 10; i++) { @@ -322,32 +307,20 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { ); // Connection is not created yet, no locking applied - expect( - connections.get(remoteNodeId1.toString() as NodeIdString), - ).not.toBeDefined(); + expect(connections.get(remoteNodeIdString1)).not.toBeDefined(); // Iterating over generator for await (const _ of gen) { // Should be locked for duration of stream - expect( - connections - .get(remoteNodeId1.toString() as NodeIdString) - ?.lock?.isLocked(), - ).toBe(true); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBe(true); } // Unlocked after stream finished - expect( - connections - .get(remoteNodeId1.toString() as NodeIdString) - ?.lock?.isLocked(), - ).toBe(false); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBe(false); - const finalConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); + const finalConnection = connections.get(remoteNodeIdString1); // Check entry is in map and lock is released - expect(finalConnLock).toBeDefined(); - expect(finalConnLock?.lock.isLocked()).toBe(false); + expect(finalConnection).toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBe(false); } finally { await nodeConnectionManager?.stop(); } @@ -371,17 +344,21 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { }); // @ts-ignore: kidnap connection map const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnap connectionLocks + const connectionLocks = nodeConnectionManager.connectionLocks; expect(connections.size).toBe(0); await expect(() => nodeConnectionManager?.withConnF(dummyNodeId, nop), ).rejects.toThrow(nodesErrors.ErrorNodeConnectionTimeout); - expect(connections.size).toBe(1); + expect(connections.size).toBe(0); const connLock = connections.get(dummyNodeId.toString() as NodeIdString); // There should still be an entry in the connection map, but it should // only contain a lock - no connection - expect(connLock).toBeDefined(); - expect(connLock?.lock).toBeDefined(); + expect(connLock).not.toBeDefined(); + expect( + connectionLocks.isLocked(dummyNodeId.toString() as NodeIdString), + ).toBe(false); expect(connLock?.connection).toBeUndefined(); // Undo the initial dummy node add @@ -403,10 +380,8 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { // @ts-ignore accessing protected NodeConnectionMap const connections = nodeConnectionManager.connections; expect(connections.size).toBe(0); - const initialConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(initialConnLock).toBeUndefined(); + const initialConnection = connections.get(remoteNodeIdString1); + expect(initialConnection).toBeUndefined(); await nodeConnectionManager.withConnF(remoteNodeId1, nop); // Check we only have this single connection expect(connections.size).toBe(1); @@ -430,11 +405,11 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { await nodeConnectionManager.start(); // @ts-ignore accessing protected NodeConnectionMap const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnap connectionLocks + const connectionLocks = nodeConnectionManager.connectionLocks; expect(connections.size).toBe(0); - const initialConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(initialConnLock).toBeUndefined(); + const initialConnection = connections.get(remoteNodeIdString1); + expect(initialConnection).toBeUndefined(); // Concurrently create connection to same target await Promise.all([ nodeConnectionManager.withConnF(remoteNodeId1, nop), @@ -442,12 +417,10 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { ]); // Check only 1 connection exists expect(connections.size).toBe(1); - const finalConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); + const finalConnection = connections.get(remoteNodeIdString1); // Check entry is in map and lock is released - expect(finalConnLock).toBeDefined(); - expect(finalConnLock?.lock.isLocked()).toBeFalsy(); + expect(finalConnection).toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBeFalsy(); } finally { await nodeConnectionManager?.stop(); } @@ -465,26 +438,22 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { await nodeConnectionManager.start(); // @ts-ignore: kidnap connections const connections = nodeConnectionManager.connections; - const initialConnLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(initialConnLock).toBeUndefined(); + // @ts-ignore: kidnap connectionLocks + const connectionLocks = nodeConnectionManager.connectionLocks; + const initialConnection = connections.get(remoteNodeIdString1); + expect(initialConnection).toBeUndefined(); await nodeConnectionManager.withConnF(remoteNodeId1, nop); - const midConnAndLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); + const midConnAndLock = connections.get(remoteNodeIdString1); // Check entry is in map and lock is released expect(midConnAndLock).toBeDefined(); - expect(midConnAndLock?.lock.isLocked()).toBeFalsy(); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBeFalsy(); // Destroying the connection // @ts-ignore: private method await nodeConnectionManager.destroyConnection(remoteNodeId1); - const finalConnAndLock = connections.get( - remoteNodeId1.toString() as NodeIdString, - ); - expect(finalConnAndLock).toBeDefined(); - expect(finalConnAndLock?.lock.isLocked()).toBeFalsy(); + const finalConnAndLock = connections.get(remoteNodeIdString1); + expect(finalConnAndLock).not.toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeIdString1)).toBeFalsy(); expect(finalConnAndLock?.connection).toBeUndefined(); } finally { await nodeConnectionManager?.stop(); @@ -507,20 +476,22 @@ describe(`${NodeConnectionManager.name} lifecycle test`, () => { // @ts-ignore: Hijack connection map const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnap connectionLocks + const connectionLocks = nodeConnectionManager.connectionLocks; expect(connections.size).toBe(2); - for (const [, connAndLock] of connections) { + for (const [nodeIdString, connAndLock] of connections) { expect(connAndLock.connection).toBeDefined(); expect(connAndLock.timer).toBeDefined(); - expect(connAndLock.lock).toBeDefined(); + expect(connectionLocks.isLocked(nodeIdString)).toBeDefined(); } // Destroying connections await nodeConnectionManager.stop(); - expect(connections.size).toBe(2); - for (const [, connAndLock] of connections) { + expect(connections.size).toBe(0); + for (const [nodeIdString, connAndLock] of connections) { expect(connAndLock.connection).toBeUndefined(); expect(connAndLock.timer).toBeUndefined(); - expect(connAndLock.lock).toBeDefined(); + expect(connectionLocks.isLocked(nodeIdString)).toBeDefined(); } } finally { // Clean up diff --git a/tests/nodes/NodeConnectionManager.termination.test.ts b/tests/nodes/NodeConnectionManager.termination.test.ts index 7cc443d07..3fa14f66c 100644 --- a/tests/nodes/NodeConnectionManager.termination.test.ts +++ b/tests/nodes/NodeConnectionManager.termination.test.ts @@ -377,6 +377,8 @@ describe(`${NodeConnectionManager.name} termination test`, () => { // @ts-ignore: kidnapping connection map const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnapping connection map + const connectionLocks = nodeConnectionManager.connectionLocks; // Connections should be empty expect(connections.size).toBe(0); @@ -392,10 +394,9 @@ describe(`${NodeConnectionManager.name} termination test`, () => { await polykeyAgent.stop(); // Connection should be removed expect(connections.size).toBe(1); - const connAndLock = connections.get( - agentNodeId.toString() as NodeIdString, - ); - expect(connAndLock?.lock.isLocked()).toBe(false); + expect( + connectionLocks.isLocked(agentNodeId.toString() as NodeIdString), + ).toBe(false); if (firstConnection != null) { expect(firstConnection[destroyed]).toBe(true); } @@ -433,6 +434,8 @@ describe(`${NodeConnectionManager.name} termination test`, () => { // @ts-ignore: kidnapping connection map const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnapping connection map + const connectionLocks = nodeConnectionManager.connectionLocks; // Connections should be empty expect(connections.size).toBe(0); @@ -464,11 +467,10 @@ describe(`${NodeConnectionManager.name} termination test`, () => { await expect(withConnectionP).rejects.toThrow(); // Connection should be removed - expect(connections.size).toBe(1); - const connAndLock = connections.get( - agentNodeId.toString() as NodeIdString, - ); - expect(connAndLock?.lock.isLocked()).toBe(false); + expect(connections.size).toBe(0); + expect( + connectionLocks.isLocked(agentNodeId.toString() as NodeIdString), + ).toBe(false); if (firstConnection != null) { expect(firstConnection[destroyed]).toBe(true); } @@ -511,6 +513,8 @@ describe(`${NodeConnectionManager.name} termination test`, () => { // @ts-ignore: kidnapping connection map const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnapping connection map + const connectionLocks = nodeConnectionManager.connectionLocks; // Connections should be empty expect(connections.size).toBe(0); @@ -540,11 +544,10 @@ describe(`${NodeConnectionManager.name} termination test`, () => { await expect(responseP).rejects.toThrow(); // Connection should be removed - expect(connections.size).toBe(1); - const connAndLock = connections.get( - agentNodeId.toString() as NodeIdString, - ); - expect(connAndLock?.lock.isLocked()).toBe(false); + expect(connections.size).toBe(0); + expect( + connectionLocks.isLocked(agentNodeId.toString() as NodeIdString), + ).toBe(false); if (firstConnection != null) { expect(firstConnection[destroyed]).toBe(true); } @@ -582,6 +585,8 @@ describe(`${NodeConnectionManager.name} termination test`, () => { // @ts-ignore: kidnapping connection map const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnapping connection map + const connectionLocks = nodeConnectionManager.connectionLocks; // Connections should be empty expect(connections.size).toBe(0); @@ -616,11 +621,10 @@ describe(`${NodeConnectionManager.name} termination test`, () => { }).rejects.toThrow(); // Connection should be removed - expect(connections.size).toBe(1); - const connAndLock = connections.get( - agentNodeId.toString() as NodeIdString, - ); - expect(connAndLock?.lock.isLocked()).toBe(false); + expect(connections.size).toBe(0); + expect( + connectionLocks.isLocked(agentNodeId.toString() as NodeIdString), + ).toBe(false); if (firstConnection != null) { expect(firstConnection[destroyed]).toBe(true); } @@ -658,6 +662,8 @@ describe(`${NodeConnectionManager.name} termination test`, () => { // @ts-ignore: kidnapping connection map const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnapping connection map + const connectionLocks = nodeConnectionManager.connectionLocks; // Connections should be empty expect(connections.size).toBe(0); @@ -693,10 +699,9 @@ describe(`${NodeConnectionManager.name} termination test`, () => { // Connection should be removed expect(connections.size).toBe(1); - const connAndLock = connections.get( - agentNodeId.toString() as NodeIdString, - ); - expect(connAndLock?.lock.isLocked()).toBe(false); + expect( + connectionLocks.isLocked(agentNodeId.toString() as NodeIdString), + ).toBe(false); if (firstConnection != null) { expect(firstConnection[destroyed]).toBe(true); } @@ -734,6 +739,8 @@ describe(`${NodeConnectionManager.name} termination test`, () => { // @ts-ignore: kidnapping connection map const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnapping connection map + const connectionLocks = nodeConnectionManager.connectionLocks; // Connections should be empty expect(connections.size).toBe(0); @@ -763,10 +770,9 @@ describe(`${NodeConnectionManager.name} termination test`, () => { // Connection should be removed expect(connections.size).toBe(1); - const connAndLock = connections.get( - agentNodeId.toString() as NodeIdString, - ); - expect(connAndLock?.lock.isLocked()).toBe(false); + expect( + connectionLocks.isLocked(agentNodeId.toString() as NodeIdString), + ).toBe(false); if (firstConnection != null) { expect(firstConnection[destroyed]).toBe(true); } diff --git a/tests/nodes/NodeConnectionManager.timeout.test.ts b/tests/nodes/NodeConnectionManager.timeout.test.ts index 5e48eaaaf..7b93b596d 100644 --- a/tests/nodes/NodeConnectionManager.timeout.test.ts +++ b/tests/nodes/NodeConnectionManager.timeout.test.ts @@ -192,13 +192,15 @@ describe(`${NodeConnectionManager.name} timeout test`, () => { await nodeConnectionManager.start(); // @ts-ignore: kidnap connections const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnap connections + const connectionLocks = nodeConnectionManager.connectionLocks; await nodeConnectionManager.withConnF(remoteNodeId1, nop); const connAndLock = connections.get( remoteNodeId1.toString() as NodeIdString, ); // Check entry is in map and lock is released expect(connAndLock).toBeDefined(); - expect(connAndLock?.lock.isLocked()).toBeFalsy(); + expect(connectionLocks.isLocked(remoteNodeId1.toString())).toBeFalsy(); expect(connAndLock?.timer).toBeDefined(); expect(connAndLock?.connection).toBeDefined(); @@ -207,10 +209,8 @@ describe(`${NodeConnectionManager.name} timeout test`, () => { const finalConnAndLock = connections.get( remoteNodeId1.toString() as NodeIdString, ); - expect(finalConnAndLock).toBeDefined(); - expect(finalConnAndLock?.lock.isLocked()).toBeFalsy(); - expect(finalConnAndLock?.timer).toBeUndefined(); - expect(finalConnAndLock?.connection).toBeUndefined(); + expect(finalConnAndLock).not.toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeId1.toString())).toBeFalsy(); } finally { await nodeConnectionManager?.stop(); } @@ -229,13 +229,15 @@ describe(`${NodeConnectionManager.name} timeout test`, () => { await nodeConnectionManager.start(); // @ts-ignore: kidnap connections const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnap connections + const connectionLocks = nodeConnectionManager.connectionLocks; await nodeConnectionManager.withConnF(remoteNodeId1, nop); const connAndLock = connections.get( remoteNodeId1.toString() as NodeIdString, ); // Check entry is in map and lock is released expect(connAndLock).toBeDefined(); - expect(connAndLock?.lock.isLocked()).toBeFalsy(); + expect(connectionLocks.isLocked(remoteNodeId1.toString())).toBeFalsy(); expect(connAndLock?.timer).toBeDefined(); expect(connAndLock?.connection).toBeDefined(); @@ -251,7 +253,7 @@ describe(`${NodeConnectionManager.name} timeout test`, () => { remoteNodeId1.toString() as NodeIdString, ); expect(midConnAndLock).toBeDefined(); - expect(midConnAndLock?.lock.isLocked()).toBeFalsy(); + expect(connectionLocks.isLocked(remoteNodeId1.toString())).toBeFalsy(); expect(midConnAndLock?.timer).toBeDefined(); expect(midConnAndLock?.connection).toBeDefined(); @@ -260,10 +262,8 @@ describe(`${NodeConnectionManager.name} timeout test`, () => { const finalConnAndLock = connections.get( remoteNodeId1.toString() as NodeIdString, ); - expect(finalConnAndLock).toBeDefined(); - expect(finalConnAndLock?.lock.isLocked()).toBeFalsy(); - expect(finalConnAndLock?.timer).toBeUndefined(); - expect(finalConnAndLock?.connection).toBeUndefined(); + expect(finalConnAndLock).not.toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeId1.toString())).toBeFalsy(); } finally { await nodeConnectionManager?.stop(); } @@ -281,13 +281,15 @@ describe(`${NodeConnectionManager.name} timeout test`, () => { await nodeConnectionManager.start(); // @ts-ignore: kidnap connections const connections = nodeConnectionManager.connections; + // @ts-ignore: kidnap connections + const connectionLocks = nodeConnectionManager.connectionLocks; await nodeConnectionManager.withConnF(remoteNodeId1, nop); const midConnAndLock = connections.get( remoteNodeId1.toString() as NodeIdString, ); // Check entry is in map and lock is released expect(midConnAndLock).toBeDefined(); - expect(midConnAndLock?.lock.isLocked()).toBeFalsy(); + expect(connectionLocks.isLocked(remoteNodeId1.toString())).toBeFalsy(); expect(midConnAndLock?.timer).toBeDefined(); // Destroying the connection @@ -296,10 +298,8 @@ describe(`${NodeConnectionManager.name} timeout test`, () => { const finalConnAndLock = connections.get( remoteNodeId1.toString() as NodeIdString, ); - expect(finalConnAndLock).toBeDefined(); - expect(finalConnAndLock?.lock.isLocked()).toBeFalsy(); - expect(finalConnAndLock?.connection).toBeUndefined(); - expect(finalConnAndLock?.timer).toBeUndefined(); + expect(finalConnAndLock).not.toBeDefined(); + expect(connectionLocks.isLocked(remoteNodeId1.toString())).toBeFalsy(); } finally { await nodeConnectionManager?.stop(); } From cd19bbab010dd0deecb50b59023668416c9edf4b Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Mon, 23 May 2022 12:57:29 +1000 Subject: [PATCH 45/74] feat: updated `VaultManager` to use `LockBox` for object map locking Using `LockBox` allowed us to greatly simplify using the object map and creating vaults. --- src/vaults/VaultManager.ts | 368 +++++++++++++----------------- tests/vaults/VaultManager.test.ts | 325 +++++++++++++------------- 2 files changed, 326 insertions(+), 367 deletions(-) diff --git a/src/vaults/VaultManager.ts b/src/vaults/VaultManager.ts index 2f8fe364f..ecf795a7f 100644 --- a/src/vaults/VaultManager.ts +++ b/src/vaults/VaultManager.ts @@ -1,5 +1,4 @@ import type { DB, DBTransaction, LevelPath } from '@matrixai/db'; -import type { ResourceAcquire, ResourceRelease } from '@matrixai/resources'; import type { VaultId, VaultName, @@ -8,7 +7,7 @@ import type { VaultIdEncoded, } from './types'; import type { Vault } from './Vault'; -import type { FileSystem } from '../types'; +import type { FileSystem, ToString } from '../types'; import type { PolykeyWorkerManagerInterface } from '../workers/types'; import type { NodeId } from '../nodes/types'; import type KeyManager from '../keys/KeyManager'; @@ -18,6 +17,7 @@ import type NotificationsManager from '../notifications/NotificationsManager'; import type ACL from '../acl/ACL'; import type { RemoteInfo } from './VaultInternal'; import type { VaultAction } from './types'; +import type { Lockable } from '@matrixai/async-locks'; import path from 'path'; import { PassThrough } from 'readable-stream'; import { EncryptedFS, errors as encryptedFsErrors } from 'encryptedfs'; @@ -28,7 +28,7 @@ import { } from '@matrixai/async-init/dist/CreateDestroyStartStop'; import { IdInternal } from '@matrixai/id'; import { withF, withG } from '@matrixai/resources'; -import { RWLockWriter } from '@matrixai/async-locks'; +import { LockBox, RWLockWriter } from '@matrixai/async-locks'; import VaultInternal from './VaultInternal'; import * as vaultsUtils from '../vaults/utils'; import * as vaultsErrors from '../vaults/errors'; @@ -43,13 +43,7 @@ import * as utilsPB from '../proto/js/polykey/v1/utils/utils_pb'; /** * Object map pattern for each vault */ -type VaultMap = Map< - VaultIdString, - { - vault?: VaultInternal; - lock: RWLockWriter; - } ->; +type VaultMap = Map; type VaultList = Map; type VaultMetadata = { @@ -58,9 +52,12 @@ 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 +// FIXME, this is a HACK since this type isn't exported +type LockRequest = [ + key: ToString, + lockConstructor: new () => L, + ...lockingParams: Parameters, +]; interface VaultManager extends CreateDestroyStartStop {} @CreateDestroyStartStop( @@ -129,6 +126,7 @@ class VaultManager { protected vaultsNamesLock: RWLockWriter = new RWLockWriter(); // VaultId -> VaultMetadata protected vaultMap: VaultMap = new Map(); + protected vaultLocks: LockBox = new LockBox(); protected vaultKey: Buffer; protected efs: EncryptedFS; @@ -224,14 +222,22 @@ 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 promises: Array> = []; + for (const vaultIdString of this.vaultMap.keys()) { const vaultId = IdInternal.fromString(vaultIdString); - await withF([this.getWriteLock(vaultId)], async () => { - await vaultAndLock.vault?.stop(); - }); - this.vaultMap.delete(vaultIdString); + promises.push( + withF( + [this.vaultLocks.lock([vaultId.toString(), RWLockWriter, 'write'])], + async () => { + const vault = this.vaultMap.get(vaultIdString); + if (vault == null) return; + await vault.stop(); + this.vaultMap.delete(vaultIdString); + }, + ), + ); } - + await Promise.all(promises); await this.efs.stop(); this.vaultMap = new Map(); this.logger.info(`Stopped ${this.constructor.name}`); @@ -242,7 +248,7 @@ class VaultManager { await this.efs.destroy(); // Clearing all vaults db data await this.db.clear(this.vaultsDbPath); - // Is it necessary to remove the vaults domain? + // Is it necessary to remove the vaults' domain? await this.fs.promises.rm(this.vaultsPath, { force: true, recursive: true, @@ -258,33 +264,10 @@ class VaultManager { this.efs.unsetWorkerManager(); } - 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 RWLockWriter(); - this.vaultMap.set(vaultIdString, { lock }); - return lock; - } - - protected getReadLock(vaultId: VaultId): ResourceAcquire { - const lock = this.getLock(vaultId); - return lock.read(); - } - - protected getWriteLock(vaultId: VaultId): ResourceAcquire { - const lock = this.getLock(vaultId); - return lock.write(); - } - /** * Constructs a new vault instance with a given name and * stores it in memory */ - - // this should actually - @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) public async createVault( vaultName: VaultName, @@ -311,31 +294,32 @@ class VaultManager { vaultId.toBuffer(), 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; - }); + return await this.vaultLocks.withF( + [vaultId, RWLockWriter, 'write'], + 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, vault); + return vault.vaultId; + }, + ); }); } /** - * Retreives the vault metadata using the vault Id + * Retrieves the vault metadata using the VaultId * and parses it to return the associated vault name */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) @@ -376,7 +360,7 @@ class VaultManager { /** * Removes the metadata and EFS state of a vault using a - * given vault Id + * given VaultId */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) public async destroyVault( @@ -394,7 +378,7 @@ class VaultManager { const vaultName = vaultMeta.vaultName; this.logger.info(`Destroying Vault ${vaultsUtils.encodeVaultId(vaultId)}`); const vaultIdString = vaultId.toString() as VaultIdString; - await withF([this.getWriteLock(vaultId)], async () => { + await this.vaultLocks.withF([vaultId, RWLockWriter, 'write'], async () => { const vault = await this.getVault(vaultId, tran); // Destroying vault state and metadata await vault.stop(); @@ -427,7 +411,7 @@ class VaultManager { throw new vaultsErrors.ErrorVaultsVaultUndefined(); } const vaultIdString = vaultId.toString() as VaultIdString; - await withF([this.getWriteLock(vaultId)], async () => { + await this.vaultLocks.withF([vaultId, RWLockWriter, 'write'], async () => { const vault = await this.getVault(vaultId, tran); await vault.stop(); this.vaultMap.delete(vaultIdString); @@ -435,7 +419,7 @@ class VaultManager { } /** - * Lists the vault name and associated vault Id of all + * Lists the vault name and associated VaultId of all * the vaults stored */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) @@ -458,7 +442,7 @@ class VaultManager { } /** - * Changes the vault name metadata of a vault Id + * Changes the vault name metadata of a VaultId */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) public async renameVault( @@ -472,7 +456,7 @@ class VaultManager { ); } - await withF([this.getWriteLock(vaultId)], async () => { + await this.vaultLocks.withF([vaultId, RWLockWriter, 'write'], async () => { this.logger.info(`Renaming Vault ${vaultsUtils.encodeVaultId(vaultId)}`); // Checking if new name exists if (await this.getVaultId(newVaultName, tran)) { @@ -503,7 +487,7 @@ class VaultManager { } /** - * Retreives the vault Id associated with a vault name + * Retrieves the VaultId associated with a vault name */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) public async getVaultId( @@ -527,7 +511,7 @@ class VaultManager { } /** - * Retreives the vault name associated with a vault Id + * Retrieves the vault name associated with a VaultId */ @ready(new vaultsErrors.ErrorVaultManagerNotRunning()) public async getVaultName( @@ -584,7 +568,7 @@ class VaultManager { const vaultMeta = await this.getVaultMeta(vaultId, tran); if (vaultMeta == null) throw new vaultsErrors.ErrorVaultsVaultUndefined(); - // Node Id permissions translated to other nodes in + // NodeId permissions translated to other nodes in // a gestalt by other domains await this.gestaltGraph.setGestaltActionByNode(nodeId, 'scan', tran); await this.acl.setVaultAction(vaultId, nodeId, 'pull', tran); @@ -640,65 +624,68 @@ class VaultManager { } const vaultId = await this.generateVaultId(); - const lock = new RWLockWriter(); const vaultIdString = vaultId.toString() as VaultIdString; - this.vaultMap.set(vaultIdString, { lock }); this.logger.info( `Cloning Vault ${vaultsUtils.encodeVaultId(vaultId)} on Node ${nodeId}`, ); - return await withF([this.getWriteLock(vaultId)], async () => { - const vault = await VaultInternal.cloneVaultInternal({ - targetNodeId: nodeId, - targetVaultNameOrId: vaultNameOrId, - vaultId, - db: this.db, - nodeConnectionManager: this.nodeConnectionManager, - 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, 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 tran.get([ - ...this.vaultsNamesDbPath, - newVaultName, - ]); - if (existingVaultId == null) break; - newVaultName = `${baseVaultName}-${attempts}`; - if (attempts >= 50) { - throw new vaultsErrors.ErrorVaultsNameConflict( - `Too many copies of ${baseVaultName}`, - ); + return await this.vaultLocks.withF( + [vaultId, RWLockWriter, 'write'], + async () => { + const vault = await VaultInternal.cloneVaultInternal({ + targetNodeId: nodeId, + targetVaultNameOrId: vaultNameOrId, + vaultId, + db: this.db, + nodeConnectionManager: this.nodeConnectionManager, + vaultsDbPath: this.vaultsDbPath, + keyManager: this.keyManager, + efs: this.efs, + logger: this.logger.getChild(VaultInternal.name), + tran, + }); + this.vaultMap.set(vaultIdString, vault); + 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 tran.get([ + ...this.vaultsNamesDbPath, + newVaultName, + ]); + if (existingVaultId == null) break; + newVaultName = `${baseVaultName}-${attempts}`; + if (attempts >= 50) { + throw new vaultsErrors.ErrorVaultsNameConflict( + `Too many copies of ${baseVaultName}`, + ); + } + attempts++; } - attempts++; - } - // Set the vaultName -> vaultId mapping - await tran.put( - [...this.vaultsNamesDbPath, newVaultName], - vaultId.toBuffer(), - true, - ); - // Update vault metadata - await tran.put( - [ - ...this.vaultsDbPath, - vaultsUtils.encodeVaultId(vaultId), - VaultInternal.nameKey, - ], - newVaultName, - ); - this.logger.info( - `Cloned Vault ${vaultsUtils.encodeVaultId(vaultId)} on Node ${nodeId}`, - ); - return vault.vaultId; - }); + // Set the vaultName -> vaultId mapping + await tran.put( + [...this.vaultsNamesDbPath, newVaultName], + vaultId.toBuffer(), + true, + ); + // Update vault metadata + await tran.put( + [ + ...this.vaultsDbPath, + vaultsUtils.encodeVaultId(vaultId), + VaultInternal.nameKey, + ], + newVaultName, + ); + this.logger.info( + `Cloned Vault ${vaultsUtils.encodeVaultId( + vaultId, + )} on Node ${nodeId}`, + ); + return vault.vaultId; + }, + ); } /** @@ -723,7 +710,7 @@ class VaultManager { } if ((await this.getVaultName(vaultId, tran)) == null) return; - await withF([this.getWriteLock(vaultId)], async () => { + await this.vaultLocks.withF([vaultId, RWLockWriter, 'write'], async () => { const vault = await this.getVault(vaultId, tran); await vault.pullVault({ nodeConnectionManager: this.nodeConnectionManager, @@ -752,7 +739,10 @@ class VaultManager { const efs = this.efs; const vault = await this.getVault(vaultId, tran); return yield* withG( - [this.getReadLock(vaultId), vault.getLock().read()], + [ + this.vaultLocks.lock([vaultId, RWLockWriter, 'read']), + vault.getLock().read(), + ], async function* (): AsyncGenerator { // Adherence to git protocol yield Buffer.from( @@ -791,7 +781,10 @@ class VaultManager { const vault = await this.getVault(vaultId, tran); return await withF( - [this.getReadLock(vaultId), vault.getLock().read()], + [ + this.vaultLocks.lock([vaultId, RWLockWriter, 'read']), + vault.getLock().read(), + ], async () => { if (body.toString().slice(4, 8) === 'want') { // Parse the request to get the wanted git object @@ -932,79 +925,30 @@ class VaultManager { ); } - let vault: VaultInternal | undefined; - let lock: RWLockWriter; const vaultIdString = vaultId.toString() as VaultIdString; - let vaultAndLock = this.vaultMap.get(vaultIdString); - if (vaultAndLock != null) { - ({ vault, lock } = vaultAndLock); - // Lock and vault exist - if (vault != null) { - return vault; - } - // Only lock exists - let release: ResourceRelease | undefined; - try { - [release] = await lock.write()(); - ({ vault } = vaultAndLock); - if (vault != null) { - return vault; - } - // Only create if the vault state already exists - if ((await this.getVaultMeta(vaultId, tran)) == null) { - throw new vaultsErrors.ErrorVaultsVaultUndefined( - `Vault ${vaultsUtils.encodeVaultId(vaultId)} doesn't exist`, - ); - } - vault = await VaultInternal.createVaultInternal({ - vaultId, - keyManager: this.keyManager, - efs: this.efs, - logger: this.logger.getChild(VaultInternal.name), - db: this.db, - vaultsDbPath: this.vaultsDbPath, - tran, - }); - vaultAndLock.vault = vault; - this.vaultMap.set(vaultIdString, vaultAndLock); - return vault; - } finally { - if (release != null) await release(); - } - } else { - // Neither vault nor lock exists - lock = new RWLockWriter(); - vaultAndLock = { lock }; - this.vaultMap.set(vaultIdString, vaultAndLock); - let release: ResourceRelease | undefined; - try { - [release] = await lock.write()(); - // Only create if the vault state already exists - if ((await this.getVaultMeta(vaultId, tran)) == null) { - throw new vaultsErrors.ErrorVaultsVaultUndefined( - `Vault ${vaultsUtils.encodeVaultId(vaultId)} doesn't exist`, - ); - } - vault = await VaultInternal.createVaultInternal({ - vaultId, - keyManager: this.keyManager, - efs: this.efs, - db: this.db, - vaultsDbPath: this.vaultsDbPath, - logger: this.logger.getChild(VaultInternal.name), - tran, - }); - vaultAndLock.vault = vault; - this.vaultMap.set(vaultIdString, vaultAndLock); - return vault; - } finally { - if (release != null) await release(); - } + // 1. get the vault, if it exists then return that + const vault = this.vaultMap.get(vaultIdString); + if (vault != null) return vault; + // No vault or state exists then we throw error? + if ((await this.getVaultMeta(vaultId, tran)) == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined( + `Vault ${vaultsUtils.encodeVaultId(vaultId)} doesn't exist`, + ); } + // 2. if the state exists then create, add to map and return that + const newVault = await VaultInternal.createVaultInternal({ + vaultId, + keyManager: this.keyManager, + efs: this.efs, + logger: this.logger.getChild(VaultInternal.name), + db: this.db, + vaultsDbPath: this.vaultsDbPath, + tran, + }); + this.vaultMap.set(vaultIdString, newVault); + return newVault; } - // THIS can also be replaced with generic withF and withG - /** * 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 @@ -1023,25 +967,21 @@ class VaultManager { ); } - // Stages: - // 1. Obtain vaults - // 2. Call function with vaults while locking the vaults - // 3. Catch any problems and preform clean up in finally - // 4. return result - - const vaults = await Promise.all( - vaultIds.map(async (vaultId) => { - return await this.getVault(vaultId, tran); - }), - ); - // Obtaining locks - const vaultLocks = vaultIds.map((vaultId) => { - return this.getReadLock(vaultId); - }); + const vaultLocks: Array> = vaultIds.map( + (vaultId) => { + return [vaultId.toString(), RWLockWriter, 'read']; + }, + ); // Running the function with locking - return await withF(vaultLocks, () => { + return await this.vaultLocks.withF(...vaultLocks, async () => { + // Getting the vaults while locked + const vaults = await Promise.all( + vaultIds.map(async (vaultId) => { + return await this.getVault(vaultId, tran); + }), + ); return f(...vaults); }); } diff --git a/tests/vaults/VaultManager.test.ts b/tests/vaults/VaultManager.test.ts index 9c7bc4021..783de4ef4 100644 --- a/tests/vaults/VaultManager.test.ts +++ b/tests/vaults/VaultManager.test.ts @@ -15,6 +15,7 @@ import { IdInternal } from '@matrixai/id'; import { DB } from '@matrixai/db'; import { destroyed, running } from '@matrixai/async-init'; import git from 'isomorphic-git'; +import { RWLockWriter } from '@matrixai/async-locks'; import ACL from '@/acl/ACL'; import GestaltGraph from '@/gestalts/GestaltGraph'; import NodeConnectionManager from '@/nodes/NodeConnectionManager'; @@ -869,9 +870,10 @@ describe('VaultManager', () => { remoteVaultId, ); - await expect(() => + await expectRemoteError( vaultManager.pullVault({ vaultId: clonedVaultId }), - ).rejects.toThrow(vaultsErrors.ErrorVaultsPermissionDenied); + vaultsErrors.ErrorVaultsPermissionDenied, + ); } finally { await vaultManager?.stop(); await vaultManager?.destroy(); @@ -962,138 +964,142 @@ describe('VaultManager', () => { await vaultManager?.destroy(); } }); - test('manage pulling from different remotes', async () => { - const vaultManager = await VaultManager.createVaultManager({ - vaultsPath, - keyManager: dummyKeyManager, - gestaltGraph: {} as GestaltGraph, - nodeConnectionManager, - acl: {} as ACL, - notificationsManager: {} as NotificationsManager, - db, - logger: logger.getChild(VaultManager.name), - }); - try { - // Initial history - await remoteKeynode1.vaultManager.withVaults( - [remoteVaultId], - async (remoteVault) => { - await remoteVault.writeF(async (efs) => { - await efs.writeFile(secretNames[0], 'success?'); - await efs.writeFile(secretNames[1], 'success?'); - }); - }, - ); - - // Setting permissions - await remoteKeynode1.gestaltGraph.setNode({ - id: localNodeIdEncoded, - chain: {}, + test( + 'manage pulling from different remotes', + async () => { + const vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + keyManager: dummyKeyManager, + gestaltGraph: {} as GestaltGraph, + nodeConnectionManager, + acl: {} as ACL, + notificationsManager: {} as NotificationsManager, + db, + logger: logger.getChild(VaultManager.name), }); - await remoteKeynode1.gestaltGraph.setGestaltActionByNode( - localNodeId, - 'scan', - ); - await remoteKeynode1.acl.setVaultAction( - remoteVaultId, - localNodeId, - 'clone', - ); - await remoteKeynode1.acl.setVaultAction( - remoteVaultId, - localNodeId, - 'pull', - ); + try { + // Initial history + await remoteKeynode1.vaultManager.withVaults( + [remoteVaultId], + async (remoteVault) => { + await remoteVault.writeF(async (efs) => { + await efs.writeFile(secretNames[0], 'success?'); + await efs.writeFile(secretNames[1], 'success?'); + }); + }, + ); - await remoteKeynode1.gestaltGraph.setNode({ - id: remoteKeynode2IdEncoded, - chain: {}, - }); - await remoteKeynode1.gestaltGraph.setGestaltActionByNode( - remoteKeynode2Id, - 'scan', - ); - await remoteKeynode1.acl.setVaultAction( - remoteVaultId, - remoteKeynode2Id, - 'clone', - ); - await remoteKeynode1.acl.setVaultAction( - remoteVaultId, - remoteKeynode2Id, - 'pull', - ); + // Setting permissions + await remoteKeynode1.gestaltGraph.setNode({ + id: localNodeIdEncoded, + chain: {}, + }); + await remoteKeynode1.gestaltGraph.setGestaltActionByNode( + localNodeId, + 'scan', + ); + await remoteKeynode1.acl.setVaultAction( + remoteVaultId, + localNodeId, + 'clone', + ); + await remoteKeynode1.acl.setVaultAction( + remoteVaultId, + localNodeId, + 'pull', + ); - const clonedVaultRemote2Id = - await remoteKeynode2.vaultManager.cloneVault( - remoteKeynode1Id, + await remoteKeynode1.gestaltGraph.setNode({ + id: remoteKeynode2IdEncoded, + chain: {}, + }); + await remoteKeynode1.gestaltGraph.setGestaltActionByNode( + remoteKeynode2Id, + 'scan', + ); + await remoteKeynode1.acl.setVaultAction( + remoteVaultId, + remoteKeynode2Id, + 'clone', + ); + await remoteKeynode1.acl.setVaultAction( remoteVaultId, + remoteKeynode2Id, + 'pull', ); - await remoteKeynode2.gestaltGraph.setNode({ - id: localNodeIdEncoded, - chain: {}, - }); - await remoteKeynode2.gestaltGraph.setGestaltActionByNode( - localNodeId, - 'scan', - ); - await remoteKeynode2.acl.setVaultAction( - clonedVaultRemote2Id, - localNodeId, - 'clone', - ); - await remoteKeynode2.acl.setVaultAction( - clonedVaultRemote2Id, - localNodeId, - 'pull', - ); - const vaultCloneId = await vaultManager.cloneVault( - remoteKeynode2Id, - clonedVaultRemote2Id, - ); + const clonedVaultRemote2Id = + await remoteKeynode2.vaultManager.cloneVault( + remoteKeynode1Id, + remoteVaultId, + ); - await remoteKeynode1.vaultManager.withVaults( - [remoteVaultId], - async (remoteVault) => { - await remoteVault.writeF(async (efs) => { - await efs.writeFile(secretNames[2], 'success?'); + await remoteKeynode2.gestaltGraph.setNode({ + id: localNodeIdEncoded, + chain: {}, + }); + await remoteKeynode2.gestaltGraph.setGestaltActionByNode( + localNodeId, + 'scan', + ); + await remoteKeynode2.acl.setVaultAction( + clonedVaultRemote2Id, + localNodeId, + 'clone', + ); + await remoteKeynode2.acl.setVaultAction( + clonedVaultRemote2Id, + localNodeId, + 'pull', + ); + const vaultCloneId = await vaultManager.cloneVault( + remoteKeynode2Id, + clonedVaultRemote2Id, + ); + + await remoteKeynode1.vaultManager.withVaults( + [remoteVaultId], + async (remoteVault) => { + await remoteVault.writeF(async (efs) => { + await efs.writeFile(secretNames[2], 'success?'); + }); + }, + ); + await vaultManager.pullVault({ + vaultId: vaultCloneId, + pullNodeId: remoteKeynode1Id, + pullVaultNameOrId: vaultName, + }); + await vaultManager.withVaults([vaultCloneId], async (vaultClone) => { + await vaultClone.readF(async (efs) => { + expect((await efs.readdir('.')).sort()).toStrictEqual( + secretNames.slice(0, 3).sort(), + ); }); - }, - ); - await vaultManager.pullVault({ - vaultId: vaultCloneId, - pullNodeId: remoteKeynode1Id, - pullVaultNameOrId: vaultName, - }); - await vaultManager.withVaults([vaultCloneId], async (vaultClone) => { - await vaultClone.readF(async (efs) => { - expect((await efs.readdir('.')).sort()).toStrictEqual( - secretNames.slice(0, 3).sort(), - ); }); - }); - await remoteKeynode1.vaultManager.withVaults( - [remoteVaultId], - async (remoteVault) => { - await remoteVault.writeF(async (efs) => { - await efs.writeFile(secretNames[3], 'second success?'); + await remoteKeynode1.vaultManager.withVaults( + [remoteVaultId], + async (remoteVault) => { + await remoteVault.writeF(async (efs) => { + await efs.writeFile(secretNames[3], 'second success?'); + }); + }, + ); + await vaultManager.pullVault({ vaultId: vaultCloneId }); + await vaultManager.withVaults([vaultCloneId], async (vaultClone) => { + await vaultClone.readF(async (efs) => { + expect((await efs.readdir('.')).sort()).toStrictEqual( + secretNames.sort(), + ); }); - }, - ); - await vaultManager.pullVault({ vaultId: vaultCloneId }); - await vaultManager.withVaults([vaultCloneId], async (vaultClone) => { - await vaultClone.readF(async (efs) => { - expect((await efs.readdir('.')).sort()).toStrictEqual( - secretNames.sort(), - ); }); - }); - } finally { - await vaultManager?.stop(); - await vaultManager?.destroy(); - } - }); + } finally { + await vaultManager?.stop(); + await vaultManager?.destroy(); + } + }, + global.failedConnectionTimeout, + ); test('able to recover metadata after complex operations', async () => { const vaultManager = await VaultManager.createVaultManager({ vaultsPath, @@ -1309,9 +1315,14 @@ describe('VaultManager', () => { // @ts-ignore: kidnap vaultManager map and grabbing lock const vaultsMap = vaultManager.vaultMap; - const vaultAndLock = vaultsMap.get(vaultId.toString() as VaultIdString); - const lock = vaultAndLock!.lock; - const [releaseWrite] = await lock.write()(); + const vault = vaultsMap.get(vaultId.toString() as VaultIdString); + // @ts-ignore: kidnap vaultManager lockBox + const vaultLocks = vaultManager.vaultLocks; + const [releaseWrite] = await vaultLocks.lock([ + vaultId, + RWLockWriter, + 'write', + ])(); // Pulling vault respects VaultManager write lock const pullP = vaultManager.pullVault({ @@ -1335,9 +1346,8 @@ describe('VaultManager', () => { ); // Respects VaultInternal write lock - const vault = vaultAndLock!.vault!; // @ts-ignore: kidnap vault lock - const vaultLock = vault.lock; + const vaultLock = vault!.lock; const [releaseVaultWrite] = await vaultLock.write()(); // Pulling vault respects VaultManager write lock gitPullMock.mockClear(); @@ -1592,26 +1602,30 @@ describe('VaultManager', () => { try { // @ts-ignore: kidnapping the map const vaultMap = vaultManager.vaultMap; + // @ts-ignore: kidnap vaultManager lockBox + const vaultLocks = vaultManager.vaultLocks; + // Create the vault const vaultId = await vaultManager.createVault('vaultName'); + const vaultIdString = vaultId.toString() as VaultIdString; // Getting and holding the lock - const vaultAndLock = vaultMap.get(vaultId.toString() as VaultIdString)!; - const lock = vaultAndLock.lock; - const vault = vaultAndLock.vault!; - const [release] = await lock.write()(); + const vault = vaultMap.get(vaultIdString)!; + const [releaseWrite] = await vaultLocks.lock([ + vaultId, + RWLockWriter, + 'write', + ])(); // Try to destroy const closeP = vaultManager.closeVault(vaultId); await sleep(1000); // Shouldn't be closed expect(vault[running]).toBe(true); - expect( - vaultMap.get(vaultId.toString() as VaultIdString)!.vault, - ).toBeDefined(); + expect(vaultMap.get(vaultIdString)).toBeDefined(); // Release the lock - await release(); + await releaseWrite(); await closeP; expect(vault[running]).toBe(false); - expect(vaultMap.get(vaultId.toString() as VaultIdString)).toBeUndefined(); + expect(vaultMap.get(vaultIdString)).toBeUndefined(); } finally { await vaultManager?.stop(); await vaultManager?.destroy(); @@ -1631,26 +1645,29 @@ describe('VaultManager', () => { try { // @ts-ignore: kidnapping the map const vaultMap = vaultManager.vaultMap; + // @ts-ignore: kidnap vaultManager lockBox + const vaultLocks = vaultManager.vaultLocks; // Create the vault const vaultId = await vaultManager.createVault('vaultName'); + const vaultIdString = vaultId.toString() as VaultIdString; // Getting and holding the lock - const vaultAndLock = vaultMap.get(vaultId.toString() as VaultIdString)!; - const lock = vaultAndLock.lock; - const vault = vaultAndLock.vault!; - const [release] = await lock.write()(); + const vault = vaultMap.get(vaultIdString)!; + const [releaseWrite] = await vaultLocks.lock([ + vaultId, + RWLockWriter, + 'write', + ])(); // Try to destroy const destroyP = vaultManager.destroyVault(vaultId); await sleep(1000); // Shouldn't be destroyed expect(vault[destroyed]).toBe(false); - expect( - vaultMap.get(vaultId.toString() as VaultIdString)!.vault, - ).toBeDefined(); + expect(vaultMap.get(vaultIdString)).toBeDefined(); // Release the lock - await release(); + await releaseWrite(); await destroyP; expect(vault[destroyed]).toBe(true); - expect(vaultMap.get(vaultId.toString() as VaultIdString)).toBeUndefined(); + expect(vaultMap.get(vaultIdString)).toBeUndefined(); } finally { await vaultManager?.stop(); await vaultManager?.destroy(); @@ -1668,14 +1685,16 @@ describe('VaultManager', () => { logger: logger.getChild(VaultManager.name), }); try { - // @ts-ignore: kidnapping the map - const vaultMap = vaultManager.vaultMap; + // @ts-ignore: kidnap vaultManager lockBox + const vaultLocks = vaultManager.vaultLocks; // Create the vault const vaultId = await vaultManager.createVault('vaultName'); // Getting and holding the lock - const vaultAndLock = vaultMap.get(vaultId.toString() as VaultIdString)!; - const lock = vaultAndLock.lock; - const [release] = await lock.write()(); + const [releaseWrite] = await vaultLocks.lock([ + vaultId, + RWLockWriter, + 'write', + ])(); // Try to use vault let finished = false; const withP = vaultManager.withVaults([vaultId], async () => { @@ -1685,7 +1704,7 @@ describe('VaultManager', () => { // Shouldn't be destroyed expect(finished).toBe(false); // Release the lock - await release(); + await releaseWrite(); await withP; expect(finished).toBe(true); } finally { @@ -1919,7 +1938,7 @@ describe('VaultManager', () => { ); expect(duplicates.length).toBe(0); - const vaultId = await vaultManager.createVault('testvault'); + const vaultId = await vaultManager.createVault('testVault'); // Now only returns duplicates generateVaultIdMock.mockReturnValue(vaultId); const asd = async () => { From f18be47d4072a0c85f8677bde48b860fdaf53de1 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 23 May 2022 15:35:18 +1000 Subject: [PATCH 46/74] feat: format json affects error logging Specifying `--format=json` will cause errors to be logged in json format. ErrorPolykeyRemote errors also now contain additional metadata about the origin node of the error. #323 --- package-lock.json | 112 ++++++++++++++++++- package.json | 3 +- src/agent/GRPCClientAgent.ts | 10 ++ src/agent/service/nodesCrossSignClaim.ts | 6 +- src/agent/service/vaultsGitPackGet.ts | 6 +- src/bin/CommandPolykey.ts | 2 + src/bin/agent/CommandStart.ts | 1 + src/bin/polykey-agent.ts | 23 ++-- src/bin/polykey.ts | 12 +-- src/bin/types.ts | 1 + src/bin/utils/ExitHandlers.ts | 27 +++-- src/bin/utils/utils.ts | 77 +++++++++++-- src/client/GRPCClientClient.ts | 64 +++++++++++ src/errors.ts | 53 +++++++-- src/grpc/utils/utils.ts | 79 +++++++------- src/types.ts | 10 ++ tests/bin/agent/lock.test.ts | 2 +- tests/bin/agent/lockall.test.ts | 14 ++- tests/bin/agent/start.test.ts | 40 ++++--- tests/bin/agent/stop.test.ts | 16 ++- tests/bin/bootstrap.test.ts | 85 +++++++-------- tests/bin/sessions.test.ts | 26 ++--- tests/bin/utils.retryAuthentication.test.ts | 2 +- tests/bin/utils.test.ts | 114 +++++++++++++++++++- tests/bin/utils.ts | 24 +++-- 25 files changed, 608 insertions(+), 201 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed3d302d6..1ef8456e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,7 +79,8 @@ "ts-node": "^10.4.0", "tsconfig-paths": "^3.9.0", "typedoc": "^0.22.15", - "typescript": "^4.5.2" + "typescript": "^4.5.2", + "typescript-cached-transpile": "0.0.6" } }, "node_modules/@ampproject/remapping": { @@ -11146,6 +11147,64 @@ "node": ">=4.2.0" } }, + "node_modules/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, + "dependencies": { + "@types/node": "^12.12.7", + "fs-extra": "^8.1.0", + "tslib": "^1.10.0" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/typescript-cached-transpile/node_modules/@types/node": { + "version": "12.20.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", + "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==", + "dev": true + }, + "node_modules/typescript-cached-transpile/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/typescript-cached-transpile/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/typescript-cached-transpile/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/typescript-cached-transpile/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/uglify-js": { "version": "3.15.5", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", @@ -19921,6 +19980,57 @@ "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "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" + }, + "dependencies": { + "@types/node": { + "version": "12.20.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.52.tgz", + "integrity": "sha512-cfkwWw72849SNYp3Zx0IcIs25vABmFh73xicxhCkTcvtZQeIez15PpwQN8fY3RD7gv1Wrxlc9MEtfMORZDEsGw==", + "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==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "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 + } + } + }, "uglify-js": { "version": "3.15.5", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", diff --git a/package.json b/package.json index 032299e22..8f6197450 100644 --- a/package.json +++ b/package.json @@ -141,6 +141,7 @@ "ts-node": "^10.4.0", "tsconfig-paths": "^3.9.0", "typedoc": "^0.22.15", - "typescript": "^4.5.2" + "typescript": "^4.5.2", + "typescript-cached-transpile": "0.0.6" } } diff --git a/src/agent/GRPCClientAgent.ts b/src/agent/GRPCClientAgent.ts index bfc1c4d65..bb4593785 100644 --- a/src/agent/GRPCClientAgent.ts +++ b/src/agent/GRPCClientAgent.ts @@ -83,6 +83,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.echo.name, }, this.client.echo, )(...args); @@ -101,6 +102,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsGitInfoGet.name, }, this.client.vaultsGitInfoGet, )(...args); @@ -120,6 +122,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsGitPackGet.name, }, this.client.vaultsGitPackGet, )(...args); @@ -138,6 +141,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsScan.name, }, this.client.vaultsScan, )(...args); @@ -151,6 +155,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesClosestLocalNodesGet.name, }, this.client.nodesClosestLocalNodesGet, )(...args); @@ -164,6 +169,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesClaimsGet.name, }, this.client.nodesClaimsGet, )(...args); @@ -177,6 +183,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesChainDataGet.name, }, this.client.nodesChainDataGet, )(...args); @@ -190,6 +197,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesHolePunchMessageSend.name, }, this.client.nodesHolePunchMessageSend, )(...args); @@ -203,6 +211,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.notificationsSend.name, }, this.client.notificationsSend, )(...args); @@ -225,6 +234,7 @@ class GRPCClientAgent extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesCrossSignClaim.name, }, this.client.nodesCrossSignClaim, )(...args); diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index f0a3e2a9a..f9fbb1bbb 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -32,7 +32,11 @@ function nodesCrossSignClaim({ call: grpc.ServerDuplexStream, ) => { const nodeId = keyManager.getNodeId(); - const genClaims = grpcUtils.generatorDuplex(call, { nodeId }, true); + const genClaims = grpcUtils.generatorDuplex( + call, + { nodeId, command: nodesCrossSignClaim.name }, + true, + ); try { await db.withTransactionF(async (tran) => { const readStatus = await genClaims.read(); diff --git a/src/agent/service/vaultsGitPackGet.ts b/src/agent/service/vaultsGitPackGet.ts index 8d9561512..c7ec95dbd 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -34,7 +34,11 @@ function vaultsGitPackGet({ call: grpc.ServerDuplexStream, ): Promise => { const nodeId = keyManager.getNodeId(); - const genDuplex = grpcUtils.generatorDuplex(call, { nodeId }, true); + const genDuplex = grpcUtils.generatorDuplex( + call, + { nodeId, command: vaultsGitPackGet.name }, + true, + ); try { const clientBodyBuffers: Uint8Array[] = []; const clientRequest = (await genDuplex.read()).value; diff --git a/src/bin/CommandPolykey.ts b/src/bin/CommandPolykey.ts index b9534fee0..436dfdbdd 100644 --- a/src/bin/CommandPolykey.ts +++ b/src/bin/CommandPolykey.ts @@ -61,6 +61,8 @@ class CommandPolykey extends commander.Command { public action(fn: (...args: any[]) => void | Promise): this { return super.action(async (...args: any[]) => { const opts = this.opts(); + // Set the format for error logging for the exit handlers + this.exitHandlers.errFormat = opts.format === 'json' ? 'json' : 'error'; // Set the logger according to the verbosity this.logger.setLevel(binUtils.verboseToLogLevel(opts.verbose)); // Set the global upstream GRPC logger diff --git a/src/bin/agent/CommandStart.ts b/src/bin/agent/CommandStart.ts index e4b863a47..6ccc4e9c0 100644 --- a/src/bin/agent/CommandStart.ts +++ b/src/bin/agent/CommandStart.ts @@ -185,6 +185,7 @@ class CommandStart extends CommandPolykey { }); const messageIn: AgentChildProcessInput = { logLevel: this.logger.getEffectiveLevel(), + format: options.format, workers: options.workers, agentConfig, }; diff --git a/src/bin/polykey-agent.ts b/src/bin/polykey-agent.ts index d56d49220..de65ebc86 100644 --- a/src/bin/polykey-agent.ts +++ b/src/bin/polykey-agent.ts @@ -44,6 +44,8 @@ async function main(_argv = process.argv): Promise { resolveMessageInP(data); }); const messageIn = await messageInP; + const errFormat = messageIn.format === 'json' ? 'json' : 'error'; + exitHandlers.errFormat = errFormat; logger.setLevel(messageIn.logLevel); // Set the global upstream GRPC logger grpcSetLogger(logger.getChild('grpc')); @@ -71,10 +73,8 @@ async function main(_argv = process.argv): Promise { if (e instanceof ErrorPolykey) { process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.description, - message: e.message, + type: errFormat, + data: e, }), ); process.exitCode = e.exitCode; @@ -82,9 +82,8 @@ async function main(_argv = process.argv): Promise { // Unknown error, this should not happen process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.message, + type: errFormat, + data: e, }), ); process.exitCode = 255; @@ -107,9 +106,8 @@ async function main(_argv = process.argv): Promise { // There's no point attempting to propagate the error to the parent process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.message, + type: errFormat, + data: e, }), ); process.exitCode = 255; @@ -137,9 +135,8 @@ async function main(_argv = process.argv): Promise { // There's no point attempting to propagate the error to the parent process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.message, + type: errFormat, + data: e, }), ); process.exitCode = 255; diff --git a/src/bin/polykey.ts b/src/bin/polykey.ts index ac40d5373..bb4d49f8a 100644 --- a/src/bin/polykey.ts +++ b/src/bin/polykey.ts @@ -55,6 +55,7 @@ async function main(argv = process.argv): Promise { // Successful execution (even if the command was non-terminating) process.exitCode = 0; } catch (e) { + const errFormat = rootCommand.opts().format === 'json' ? 'json' : 'error'; if (e instanceof commander.CommanderError) { // Commander writes help and error messages on stderr automatically if ( @@ -78,10 +79,8 @@ async function main(argv = process.argv): Promise { } else if (e instanceof ErrorPolykey) { process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.description, - message: e.message, + type: errFormat, + data: e, }), ); process.exitCode = e.exitCode; @@ -89,9 +88,8 @@ async function main(argv = process.argv): Promise { // Unknown error, this should not happen process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.message, + type: errFormat, + data: e, }), ); process.exitCode = 255; diff --git a/src/bin/types.ts b/src/bin/types.ts index ef2451661..0517f08f1 100644 --- a/src/bin/types.ts +++ b/src/bin/types.ts @@ -17,6 +17,7 @@ type AgentStatusLiveData = Omit & { */ type AgentChildProcessInput = { logLevel: LogLevel; + format: 'human' | 'json'; workers?: number; agentConfig: { password: string; diff --git a/src/bin/utils/ExitHandlers.ts b/src/bin/utils/ExitHandlers.ts index 84b981d80..2fdd74f03 100644 --- a/src/bin/utils/ExitHandlers.ts +++ b/src/bin/utils/ExitHandlers.ts @@ -9,6 +9,7 @@ class ExitHandlers { */ public handlers: Array<(signal?: NodeJS.Signals) => Promise>; protected _exiting: boolean = false; + protected _errFormat: 'json' | 'error'; /** * Handles synchronous and asynchronous exceptions * This prints out appropriate error message on STDERR @@ -23,10 +24,8 @@ class ExitHandlers { if (e instanceof ErrorPolykey) { process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.description, - message: e.message, + type: this._errFormat, + data: e, }), ); process.exitCode = e.exitCode; @@ -34,9 +33,8 @@ class ExitHandlers { // Unknown error, this should not happen process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.message, + type: this._errFormat, + data: e, }), ); process.exitCode = 255; @@ -65,19 +63,16 @@ class ExitHandlers { if (e instanceof ErrorPolykey) { process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.description, - message: e.message, + type: this._errFormat, + data: e, }), ); } else { // Unknown error, this should not happen process.stderr.write( binUtils.outputFormatter({ - type: 'error', - name: e.name, - description: e.message, + type: this._errFormat, + data: e, }), ); } @@ -103,6 +98,10 @@ class ExitHandlers { return this._exiting; } + set errFormat(errFormat: 'json' | 'error') { + this._errFormat = errFormat; + } + public install() { process.on('SIGINT', this.signalHandler); process.on('SIGTERM', this.signalHandler); diff --git a/src/bin/utils/utils.ts b/src/bin/utils/utils.ts index 5477228a9..0e66b8e23 100644 --- a/src/bin/utils/utils.ts +++ b/src/bin/utils/utils.ts @@ -2,11 +2,14 @@ import type { POJO } from '../../types'; import process from 'process'; import { LogLevel } from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; +import { AbstractError } from '@matrixai/errors'; 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'; +import * as nodesUtils from '../../nodes/utils'; +import * as utils from '../../utils'; /** * Convert verbosity to LogLevel @@ -40,9 +43,7 @@ type OutputObject = } | { type: 'error'; - name: string; - description: string; - message?: string; + data: Error; }; function outputFormatter(msg: OutputObject): string { @@ -92,14 +93,72 @@ function outputFormatter(msg: OutputObject): string { output += `${key}\t${value}\n`; } } else if (msg.type === 'json') { + if (msg.data instanceof Error && !(msg.data instanceof AbstractError)) { + msg.data = { + type: msg.data.name, + data: { message: msg.data.message, stack: msg.data.stack }, + }; + } output = JSON.stringify(msg.data); output += '\n'; } else if (msg.type === 'error') { - output += `${msg.name}: ${msg.description}`; - if (msg.message) { - output += ` - ${msg.message}`; + let currError = msg.data; + let indent = ' '; + while (currError != null) { + if (currError instanceof errors.ErrorPolykeyRemote) { + output += `${currError.name}: ${currError.description}`; + if (currError.message && currError.message !== '') { + output += ` - ${currError.message}`; + } + output += '\n'; + output += `${indent}command\t${currError.metadata.command}\n`; + output += `${indent}nodeId\t${nodesUtils.encodeNodeId( + currError.metadata.nodeId, + )}\n`; + output += `${indent}host\t${currError.metadata.host}\n`; + output += `${indent}port\t${currError.metadata.port}\n`; + output += `${indent}timestamp\t${currError.timestamp}\n`; + output += `${indent}remote error: `; + currError = currError.cause; + } else if (currError instanceof errors.ErrorPolykey) { + output += `${currError.name}: ${currError.description}`; + if (currError.message && currError.message !== '') { + output += ` - ${currError.message}`; + } + output += '\n'; + output += `${indent}exitCode\t${currError.exitCode}\n`; + output += `${indent}timestamp\t${currError.timestamp}\n`; + if (currError.data && !utils.isEmptyObject(currError.data)) { + output += `${indent}data\t${JSON.stringify(currError.data)}\n`; + } + if (currError.cause) { + output += `${indent}cause: `; + if (currError.cause instanceof errors.ErrorPolykey) { + currError = currError.cause; + } else if (currError.cause instanceof Error) { + output += `${currError.cause.name}`; + if (currError.cause.message && currError.cause.message !== '') { + output += `: ${currError.cause.message}`; + } + output += '\n'; + break; + } else { + output += `${JSON.stringify(currError.cause)}\n`; + break; + } + } else { + break; + } + } else { + output += `${currError.name}`; + if (currError.message && currError.message !== '') { + output += `: ${currError.message}`; + } + output += '\n'; + break; + } + indent = indent + ' '; } - output += '\n'; } return output; } @@ -155,8 +214,8 @@ async function retryAuthentication( function remoteErrorCause(e: any): [any, number] { let errorCause = e; let depth = 0; - while (e instanceof errors.ErrorPolykeyRemote) { - errorCause = e.cause; + while (errorCause instanceof errors.ErrorPolykeyRemote) { + errorCause = errorCause.cause; depth++; } return [errorCause, depth]; diff --git a/src/client/GRPCClientClient.ts b/src/client/GRPCClientClient.ts index e866ec475..9492841ed 100644 --- a/src/client/GRPCClientClient.ts +++ b/src/client/GRPCClientClient.ts @@ -95,6 +95,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.agentStatus.name, }, this.client.agentStatus, )(...args); @@ -108,6 +109,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.agentStop.name, }, this.client.agentStop, )(...args); @@ -121,6 +123,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.agentUnlock.name, }, this.client.agentUnlock, )(...args); @@ -134,6 +137,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.agentLockAll.name, }, this.client.agentLockAll, )(...args); @@ -152,6 +156,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsList.name, }, this.client.vaultsList, )(...args); @@ -165,6 +170,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsCreate.name, }, this.client.vaultsCreate, )(...args); @@ -178,6 +184,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsRename.name, }, this.client.vaultsRename, )(...args); @@ -191,6 +198,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsDelete.name, }, this.client.vaultsDelete, )(...args); @@ -204,6 +212,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsClone.name, }, this.client.vaultsClone, )(...args); @@ -217,6 +226,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsPull.name, }, this.client.vaultsPull, )(...args); @@ -235,6 +245,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsScan.name, }, this.client.vaultsScan, )(...args); @@ -248,6 +259,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsPermissionGet.name, }, this.client.vaultsPermissionGet, )(...args); @@ -261,6 +273,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsPermissionSet.name, }, this.client.vaultsPermissionSet, )(...args); @@ -274,6 +287,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsPermissionUnset.name, }, this.client.vaultsPermissionUnset, )(...args); @@ -292,6 +306,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsList.name, }, this.client.vaultsSecretsList, )(...args); @@ -305,6 +320,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsMkdir.name, }, this.client.vaultsSecretsMkdir, )(...args); @@ -318,6 +334,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsDelete.name, }, this.client.vaultsSecretsDelete, )(...args); @@ -331,6 +348,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsEdit.name, }, this.client.vaultsSecretsEdit, )(...args); @@ -344,6 +362,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsGet.name, }, this.client.vaultsSecretsGet, )(...args); @@ -357,6 +376,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsStat.name, }, this.client.vaultsSecretsStat, )(...args); @@ -370,6 +390,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsRename.name, }, this.client.vaultsSecretsRename, )(...args); @@ -383,6 +404,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsNew.name, }, this.client.vaultsSecretsNew, )(...args); @@ -396,6 +418,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsSecretsNewDir.name, }, this.client.vaultsSecretsNewDir, )(...args); @@ -409,6 +432,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsVersion.name, }, this.client.vaultsVersion, )(...args); @@ -427,6 +451,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.vaultsLog.name, }, this.client.vaultsLog, )(...args); @@ -440,6 +465,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysKeyPairRoot.name, }, this.client.keysKeyPairRoot, )(...args); @@ -453,6 +479,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysKeyPairReset.name, }, this.client.keysKeyPairReset, )(...args); @@ -466,6 +493,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysKeyPairRenew.name, }, this.client.keysKeyPairRenew, )(...args); @@ -479,6 +507,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysEncrypt.name, }, this.client.keysEncrypt, )(...args); @@ -492,6 +521,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysDecrypt.name, }, this.client.keysDecrypt, )(...args); @@ -505,6 +535,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysSign.name, }, this.client.keysSign, )(...args); @@ -518,6 +549,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysVerify.name, }, this.client.keysVerify, )(...args); @@ -531,6 +563,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysPasswordChange.name, }, this.client.keysPasswordChange, )(...args); @@ -544,6 +577,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysCertsGet.name, }, this.client.keysCertsGet, )(...args); @@ -562,6 +596,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.keysCertsGet.name, }, this.client.keysCertsChainGet, )(...args); @@ -580,6 +615,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsGestaltList.name, }, this.client.gestaltsGestaltList, )(...args); @@ -593,6 +629,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsGestaltGetByIdentity.name, }, this.client.gestaltsGestaltGetByIdentity, )(...args); @@ -606,6 +643,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsGestaltGetByNode.name, }, this.client.gestaltsGestaltGetByNode, )(...args); @@ -619,6 +657,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsDiscoveryByNode.name, }, this.client.gestaltsDiscoveryByNode, )(...args); @@ -632,6 +671,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsDiscoveryByIdentity.name, }, this.client.gestaltsDiscoveryByIdentity, )(...args); @@ -645,6 +685,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsActionsGetByNode.name, }, this.client.gestaltsActionsGetByNode, )(...args); @@ -658,6 +699,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsActionsGetByIdentity.name, }, this.client.gestaltsActionsGetByIdentity, )(...args); @@ -671,6 +713,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsActionsSetByNode.name, }, this.client.gestaltsActionsSetByNode, )(...args); @@ -684,6 +727,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsActionsSetByIdentity.name, }, this.client.gestaltsActionsSetByIdentity, )(...args); @@ -697,6 +741,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsActionsUnsetByNode.name, }, this.client.gestaltsActionsUnsetByNode, )(...args); @@ -710,6 +755,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsActionsUnsetByIdentity.name, }, this.client.gestaltsActionsUnsetByIdentity, )(...args); @@ -723,6 +769,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsGestaltTrustByNode.name, }, this.client.gestaltsGestaltTrustByNode, )(...args); @@ -736,6 +783,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.gestaltsGestaltTrustByIdentity.name, }, this.client.gestaltsGestaltTrustByIdentity, )(...args); @@ -749,6 +797,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesTokenPut.name, }, this.client.identitiesTokenPut, )(...args); @@ -762,6 +811,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesTokenGet.name, }, this.client.identitiesTokenGet, )(...args); @@ -775,6 +825,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesTokenDelete.name, }, this.client.identitiesTokenDelete, )(...args); @@ -788,6 +839,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesProvidersList.name, }, this.client.identitiesProvidersList, )(...args); @@ -801,6 +853,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesAdd.name, }, this.client.nodesAdd, )(...args); @@ -814,6 +867,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesPing.name, }, this.client.nodesPing, )(...args); @@ -827,6 +881,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesClaim.name, }, this.client.nodesClaim, )(...args); @@ -840,6 +895,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.nodesFind.name, }, this.client.nodesFind, )(...args); @@ -853,6 +909,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesAuthenticate.name, }, this.client.identitiesAuthenticate, )(...args); @@ -866,6 +923,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesInfoConnectedGet.name, }, this.client.identitiesInfoConnectedGet, )(...args); @@ -879,6 +937,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesInfoGet.name, }, this.client.identitiesInfoGet, )(...args); @@ -892,6 +951,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesClaim.name, }, this.client.identitiesClaim, )(...args); @@ -905,6 +965,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.identitiesAuthenticatedGet.name, }, this.client.identitiesAuthenticatedGet, )(...args); @@ -918,6 +979,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.notificationsSend.name, }, this.client.notificationsSend, )(...args); @@ -931,6 +993,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.notificationsRead.name, }, this.client.notificationsRead, )(...args); @@ -944,6 +1007,7 @@ class GRPCClientClient extends GRPCClient { nodeId: this.nodeId, host: this.host, port: this.port, + command: this.notificationsClear.name, }, this.client.notificationsClear, )(...args); diff --git a/src/errors.ts b/src/errors.ts index 53ec7b8ed..139744171 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,6 +1,52 @@ +import type { Class } from '@matrixai/errors'; +import type { ClientMetadata } from './types'; import ErrorPolykey from './ErrorPolykey'; import sysexits from './utils/sysexits'; +class ErrorPolykeyRemote extends ErrorPolykey { + static description = 'Remote error from RPC call'; + exitCode = sysexits.UNAVAILABLE; + metadata: ClientMetadata; + + constructor(metadata: ClientMetadata, message?: string, options?) { + super(message, options); + this.metadata = metadata; + } + + 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.metadata !== 'object' || + 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.metadata, 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.metadata = this.metadata; + return json; + } +} + class ErrorPolykeyUnimplemented extends ErrorPolykey { static description = 'This is an unimplemented functionality'; exitCode = sysexits.UNAVAILABLE; @@ -8,12 +54,7 @@ class ErrorPolykeyUnimplemented extends ErrorPolykey { class ErrorPolykeyUnknown extends ErrorPolykey { static description = 'Unable to deserialise to known error'; - exitCode = sysexits.UNKNOWN; -} - -class ErrorPolykeyRemote extends ErrorPolykey { - static description = 'Remote error from RPC call'; - exitCode = sysexits.UNAVAILABLE; + exitCode = sysexits.PROTOCOL; } class ErrorPolykeyAgentRunning extends ErrorPolykey { diff --git a/src/grpc/utils/utils.ts b/src/grpc/utils/utils.ts index f99331585..f37442e41 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -28,14 +28,14 @@ import type { AsyncGeneratorDuplexStreamClient, } from '../types'; import type { CertificatePemChain, PrivateKeyPem } from '../../keys/types'; -import type { POJO } from '../../types'; +import type { POJO, ClientMetadata } from '../../types'; +import type { NodeId } from '../../nodes/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'; /** @@ -184,9 +184,11 @@ function fromError( * Deserialized GRPC errors into ErrorPolykey * Use this on the receiving side to receive exceptions */ -function toError(e: ServiceError): errors.ErrorPolykey { +function toError( + e: ServiceError, + metadata: ClientMetadata, +): 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 @@ -197,10 +199,17 @@ function toError(e: ServiceError): errors.ErrorPolykey { if (isNaN(parseInt(key)) && e.code === grpc.status[key]) { if (key === 'UNKNOWN' && errorData != null) { const error: Error = JSON.parse(errorData, reviver); - return new errors.ErrorPolykeyRemote(error.message, { - data: JSON.parse(connInfo), - cause: error, - }); + const remoteError = new errors.ErrorPolykeyRemote( + metadata, + error.message, + { + cause: error, + }, + ); + if (error instanceof errors.ErrorPolykey) { + remoteError.exitCode = error.exitCode; + } + return remoteError; } else { return new grpcErrors.ErrorGRPCClientCall(e.message, { data: { @@ -344,14 +353,6 @@ function reviver(key: string, value: any): any { }, }); 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; } @@ -364,7 +365,7 @@ function reviver(key: string, value: any): any { */ function promisifyUnaryCall( client: Client, - metadata: POJO, + metadata: ClientMetadata, f: (...args: any[]) => ClientUnaryCall, ): (...args: any[]) => PromiseUnaryCall { return (...args) => { @@ -376,11 +377,7 @@ 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)); + rejectP(toError(error, metadata)); return; } resolveP(values.length === 1 ? values[0] : values); @@ -405,15 +402,15 @@ function promisifyUnaryCall( */ function generatorReadable( stream: ClientReadableStream, - metadata: POJO, + metadata: { nodeId: NodeId; command: string } & POJO, ): AsyncGeneratorReadableStream>; function generatorReadable( stream: ServerReadableStream, - metadata: POJO, + metadata: { nodeId: NodeId; command: string } & POJO, ): AsyncGeneratorReadableStream>; function generatorReadable( stream: ClientReadableStream | ServerReadableStream, - metadata: POJO, + metadata: { nodeId: NodeId; command: string } & POJO, ) { const peerAddress = stream .getPeer() @@ -426,9 +423,12 @@ function generatorReadable( if (!('port' in metadata) && peerAddress != null) { metadata.port = networkUtils.parseAddress(peerAddress[0])[1]; } - if ('nodeId' in metadata) { - metadata.nodeId = nodesUtils.encodeNodeId(metadata.nodeId); - } + const clientMetadata: ClientMetadata = { + nodeId: metadata.nodeId, + host: metadata.host, + port: metadata.port, + command: metadata.command, + }; const gf = async function* () { try { let vR = yield; @@ -449,8 +449,7 @@ function generatorReadable( } } catch (e) { stream.destroy(); - e.metadata.set('metadata', JSON.stringify(metadata)); - throw toError(e); + throw toError(e, clientMetadata); } }; const g: any = gf(); @@ -467,7 +466,7 @@ function generatorReadable( */ function promisifyReadableStreamCall( client: grpc.Client, - metadata: POJO, + metadata: ClientMetadata, f: (...args: any[]) => ClientReadableStream, ): ( ...args: any[] @@ -539,7 +538,7 @@ function generatorWritable( */ function promisifyWritableStreamCall( client: grpc.Client, - metadata: POJO, + metadata: ClientMetadata, f: (...args: any[]) => ClientWritableStream, ): ( ...args: any[] @@ -555,11 +554,7 @@ 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 rejectP(toError(error, metadata)); } return resolveP(values.length === 1 ? values[0] : values); }; @@ -591,17 +586,17 @@ function promisifyWritableStreamCall( */ function generatorDuplex( stream: ClientDuplexStream, - metadata: POJO, + metadata: { nodeId: NodeId; command: string } & POJO, sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ServerDuplexStream, - metadata: POJO, + metadata: { nodeId: NodeId; command: string } & POJO, sensitive: boolean, ): AsyncGeneratorDuplexStream>; function generatorDuplex( stream: ClientDuplexStream | ServerDuplexStream, - metadata: POJO, + metadata: { nodeId: NodeId; command: string } & POJO, sensitive: boolean = false, ) { const gR = generatorReadable(stream as any, metadata); @@ -654,7 +649,7 @@ function generatorDuplex( */ function promisifyDuplexStreamCall( client: grpc.Client, - metadata: POJO, + metadata: ClientMetadata, f: (...args: any[]) => ClientDuplexStream, ): ( ...args: any[] @@ -699,4 +694,6 @@ export { promisifyDuplexStreamCall, toError, fromError, + replacer, + reviver, }; diff --git a/src/types.ts b/src/types.ts index 8fba1fc08..0e41f366f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,7 @@ // eslint-disable-next-line no-restricted-imports -- Interim types for FileSystem import type fs from 'fs'; +import type { Host, Port } from './network/types'; +import type { NodeId } from './nodes/types'; /** * Plain data dictionary @@ -77,6 +79,13 @@ interface FileSystem { type FileHandle = fs.promises.FileHandle; +type ClientMetadata = { + nodeId: NodeId; + host: Host; + port: Port; + command: string; +} & POJO; + export type { POJO, Opaque, @@ -89,4 +98,5 @@ export type { Timer, FileSystem, FileHandle, + ClientMetadata, }; diff --git a/tests/bin/agent/lock.test.ts b/tests/bin/agent/lock.test.ts index 012bbcaf1..a35719991 100644 --- a/tests/bin/agent/lock.test.ts +++ b/tests/bin/agent/lock.test.ts @@ -1,7 +1,7 @@ import path from 'path'; import fs from 'fs'; import prompts from 'prompts'; -import { mocked } from 'ts-jest/utils'; +import { mocked } from 'jest-mock'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import Session from '@/sessions/Session'; import config from '@/config'; diff --git a/tests/bin/agent/lockall.test.ts b/tests/bin/agent/lockall.test.ts index c0096ff14..1f39d4b9e 100644 --- a/tests/bin/agent/lockall.test.ts +++ b/tests/bin/agent/lockall.test.ts @@ -1,11 +1,11 @@ import path from 'path'; import fs from 'fs'; import prompts from 'prompts'; -import { mocked } from 'ts-jest/utils'; +import { mocked } from 'jest-mock'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import Session from '@/sessions/Session'; import config from '@/config'; -import * as clientErrors from '@/client/errors'; +import * as errors from '@/errors'; import * as testBinUtils from '../utils'; import * as testUtils from '../../utils'; @@ -113,17 +113,15 @@ describe('lockall', () => { ); // Old token is invalid const { exitCode, stderr } = await testBinUtils.pkStdio( - ['agent', 'status'], + ['agent', 'status', '--format', 'json'], { PK_NODE_PATH: globalAgentDir, PK_TOKEN: token, }, globalAgentDir, ); - testBinUtils.expectProcessError( - exitCode, - stderr, - new clientErrors.ErrorClientAuthDenied(), - ); + testBinUtils.expectProcessError(exitCode, stderr, [ + new errors.ErrorClientAuthDenied(), + ]); }); }); diff --git a/tests/bin/agent/start.test.ts b/tests/bin/agent/start.test.ts index 06a83f544..6b419fde0 100644 --- a/tests/bin/agent/start.test.ts +++ b/tests/bin/agent/start.test.ts @@ -218,6 +218,8 @@ describe('start', () => { '--workers', '0', '--verbose', + '--format', + 'json', ], { PK_NODE_PATH: path.join(dataDir, 'polykey'), @@ -239,6 +241,8 @@ describe('start', () => { '--workers', '0', '--verbose', + '--format', + 'json', ], { PK_NODE_PATH: path.join(dataDir, 'polykey'), @@ -274,21 +278,17 @@ describe('start', () => { const errorStatusLocked = new statusErrors.ErrorStatusLocked(); // It's either the first or second process if (index === 0) { - testBinUtils.expectProcessError( - exitCode!, - stdErrLine1, + testBinUtils.expectProcessError(exitCode!, stdErrLine1, [ errorStatusLocked, - ); + ]); agentProcess2.kill('SIGQUIT'); [exitCode, signal] = await testBinUtils.processExit(agentProcess2); expect(exitCode).toBe(null); expect(signal).toBe('SIGQUIT'); } else if (index === 1) { - testBinUtils.expectProcessError( - exitCode!, - stdErrLine2, + testBinUtils.expectProcessError(exitCode!, stdErrLine2, [ errorStatusLocked, - ); + ]); agentProcess1.kill('SIGQUIT'); [exitCode, signal] = await testBinUtils.processExit(agentProcess1); expect(exitCode).toBe(null); @@ -316,6 +316,8 @@ describe('start', () => { '--workers', '0', '--verbose', + '--format', + 'json', ], { PK_NODE_PATH: path.join(dataDir, 'polykey'), @@ -325,7 +327,15 @@ describe('start', () => { logger.getChild('agentProcess'), ), testBinUtils.pkSpawn( - ['bootstrap', '--fresh', '--root-key-pair-bits', '1024', '--verbose'], + [ + 'bootstrap', + '--fresh', + '--root-key-pair-bits', + '1024', + '--verbose', + '--format', + 'json', + ], { PK_NODE_PATH: path.join(dataDir, 'polykey'), PK_PASSWORD: password, @@ -360,21 +370,17 @@ describe('start', () => { const errorStatusLocked = new statusErrors.ErrorStatusLocked(); // It's either the first or second process if (index === 0) { - testBinUtils.expectProcessError( - exitCode!, - stdErrLine1, + testBinUtils.expectProcessError(exitCode!, stdErrLine1, [ errorStatusLocked, - ); + ]); bootstrapProcess.kill('SIGTERM'); [exitCode, signal] = await testBinUtils.processExit(bootstrapProcess); expect(exitCode).toBe(null); expect(signal).toBe('SIGTERM'); } else if (index === 1) { - testBinUtils.expectProcessError( - exitCode!, - stdErrLine2, + testBinUtils.expectProcessError(exitCode!, stdErrLine2, [ errorStatusLocked, - ); + ]); agentProcess.kill('SIGTERM'); [exitCode, signal] = await testBinUtils.processExit(agentProcess); expect(exitCode).toBe(null); diff --git a/tests/bin/agent/stop.test.ts b/tests/bin/agent/stop.test.ts index c22843e45..b56f9b42c 100644 --- a/tests/bin/agent/stop.test.ts +++ b/tests/bin/agent/stop.test.ts @@ -197,17 +197,15 @@ describe('stop', () => { ); await status.waitFor('STARTING'); const { exitCode, stderr } = await testBinUtils.pkStdio( - ['agent', 'stop'], + ['agent', 'stop', '--format', 'json'], { PK_NODE_PATH: path.join(dataDir, 'polykey'), }, dataDir, ); - testBinUtils.expectProcessError( - exitCode, - stderr, + testBinUtils.expectProcessError(exitCode, stderr, [ new binErrors.ErrorCLIPolykeyAgentStatus('agent is starting'), - ); + ]); await status.waitFor('LIVE'); await testBinUtils.pkStdio( ['agent', 'stop'], @@ -256,18 +254,16 @@ describe('stop', () => { logger, }); const { exitCode, stderr } = await testBinUtils.pkStdio( - ['agent', 'stop'], + ['agent', 'stop', '--format', 'json'], { PK_NODE_PATH: path.join(dataDir, 'polykey'), PK_PASSWORD: 'wrong password', }, dataDir, ); - testBinUtils.expectProcessError( - exitCode, - stderr, + testBinUtils.expectProcessError(exitCode, stderr, [ new clientErrors.ErrorClientAuthDenied(), - ); + ]); // Should still be LIVE await sleep(500); const statusInfo = await status.readStatus(); diff --git a/tests/bin/bootstrap.test.ts b/tests/bin/bootstrap.test.ts index c108d0345..409afc4f7 100644 --- a/tests/bin/bootstrap.test.ts +++ b/tests/bin/bootstrap.test.ts @@ -5,7 +5,6 @@ import readline from 'readline'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { errors as statusErrors } from '@/status'; import { errors as bootstrapErrors } from '@/bootstrap'; -import * as binUtils from '@/bin/utils'; import * as testBinUtils from './utils'; describe('bootstrap', () => { @@ -68,6 +67,8 @@ describe('bootstrap', () => { '--root-key-pair-bits', '1024', '--verbose', + '--format', + 'json', ], { PK_PASSWORD: password, @@ -76,17 +77,9 @@ describe('bootstrap', () => { )); const errorBootstrapExistingState = new bootstrapErrors.ErrorBootstrapExistingState(); - expect(exitCode).toBe(errorBootstrapExistingState.exitCode); - const stdErrLine = stderr.trim().split('\n').pop(); - const eOutput = binUtils - .outputFormatter({ - type: 'error', - name: errorBootstrapExistingState.name, - description: errorBootstrapExistingState.description, - message: errorBootstrapExistingState.message, - }) - .trim(); - expect(stdErrLine).toBe(eOutput); + testBinUtils.expectProcessError(exitCode, stderr, [ + errorBootstrapExistingState, + ]); ({ exitCode, stdout, stderr } = await testBinUtils.pkStdio( [ 'bootstrap', @@ -117,7 +110,14 @@ describe('bootstrap', () => { const password = 'password'; const [bootstrapProcess1, bootstrapProcess2] = await Promise.all([ testBinUtils.pkSpawn( - ['bootstrap', '--root-key-pair-bits', '1024', '--verbose'], + [ + 'bootstrap', + '--root-key-pair-bits', + '1024', + '--verbose', + '--format', + 'json', + ], { PK_NODE_PATH: path.join(dataDir, 'polykey'), PK_PASSWORD: password, @@ -126,7 +126,14 @@ describe('bootstrap', () => { logger.getChild('bootstrapProcess1'), ), testBinUtils.pkSpawn( - ['bootstrap', '--root-key-pair-bits', '1024', '--verbose'], + [ + 'bootstrap', + '--root-key-pair-bits', + '1024', + '--verbose', + '--format', + 'json', + ], { PK_NODE_PATH: path.join(dataDir, 'polykey'), PK_PASSWORD: password, @@ -158,27 +165,22 @@ describe('bootstrap', () => { }); }); const errorStatusLocked = new statusErrors.ErrorStatusLocked(); - expect(exitCode).toBe(errorStatusLocked.exitCode); expect(signal).toBe(null); - const eOutput = binUtils - .outputFormatter({ - type: 'error', - name: errorStatusLocked.name, - description: errorStatusLocked.description, - message: errorStatusLocked.message, - }) - .trim(); // It's either the first or second process if (index === 0) { expect(stdErrLine1).toBeDefined(); - expect(stdErrLine1).toBe(eOutput); - const [exitCode] = await testBinUtils.processExit(bootstrapProcess2); - expect(exitCode).toBe(0); + testBinUtils.expectProcessError(exitCode!, stdErrLine1, [ + errorStatusLocked, + ]); + const [exitCode2] = await testBinUtils.processExit(bootstrapProcess2); + expect(exitCode2).toBe(0); } else if (index === 1) { expect(stdErrLine2).toBeDefined(); - expect(stdErrLine2).toBe(eOutput); - const [exitCode] = await testBinUtils.processExit(bootstrapProcess1); - expect(exitCode).toBe(0); + testBinUtils.expectProcessError(exitCode!, stdErrLine2, [ + errorStatusLocked, + ]); + const [exitCode2] = await testBinUtils.processExit(bootstrapProcess1); + expect(exitCode2).toBe(0); } }, global.defaultTimeout * 2, @@ -217,28 +219,27 @@ describe('bootstrap', () => { expect(signal).toBe('SIGINT'); // Attempting to bootstrap should fail with existing state const bootstrapProcess2 = await testBinUtils.pkStdio( - ['bootstrap', '--root-key-pair-bits', '1024', '--verbose'], + [ + 'bootstrap', + '--root-key-pair-bits', + '1024', + '--verbose', + '--format', + 'json', + ], { PK_NODE_PATH: path.join(dataDir, 'polykey'), PK_PASSWORD: password, }, dataDir, ); - const stdErrLine = bootstrapProcess2.stderr.trim().split('\n').pop(); const errorBootstrapExistingState = new bootstrapErrors.ErrorBootstrapExistingState(); - expect(bootstrapProcess2.exitCode).toBe( - errorBootstrapExistingState.exitCode, + testBinUtils.expectProcessError( + bootstrapProcess2.exitCode, + bootstrapProcess2.stderr, + [errorBootstrapExistingState], ); - const eOutput = binUtils - .outputFormatter({ - type: 'error', - name: errorBootstrapExistingState.name, - description: errorBootstrapExistingState.description, - message: errorBootstrapExistingState.message, - }) - .trim(); - expect(stdErrLine).toBe(eOutput); // Attempting to bootstrap with --fresh should succeed const bootstrapProcess3 = await testBinUtils.pkStdio( ['bootstrap', '--root-key-pair-bits', '1024', '--fresh', '--verbose'], diff --git a/tests/bin/sessions.test.ts b/tests/bin/sessions.test.ts index b688eb2ef..0487b9f97 100644 --- a/tests/bin/sessions.test.ts +++ b/tests/bin/sessions.test.ts @@ -6,7 +6,7 @@ import os from 'os'; import path from 'path'; import fs from 'fs'; -import { mocked } from 'ts-jest/utils'; +import { mocked } from 'jest-mock'; import prompts from 'prompts'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { Session } from '@/sessions'; @@ -83,7 +83,7 @@ describe('sessions', () => { let exitCode, stderr; // Password and Token set ({ exitCode, stderr } = await testBinUtils.pkStdio( - ['agent', 'status'], + ['agent', 'status', '--format', 'json'], { PK_NODE_PATH: globalAgentDir, PK_PASSWORD: 'invalid', @@ -91,14 +91,12 @@ describe('sessions', () => { }, globalAgentDir, )); - testBinUtils.expectProcessError( - exitCode, - stderr, + testBinUtils.expectProcessError(exitCode, stderr, [ new clientErrors.ErrorClientAuthDenied(), - ); + ]); // Password set ({ exitCode, stderr } = await testBinUtils.pkStdio( - ['agent', 'status'], + ['agent', 'status', '--format', 'json'], { PK_NODE_PATH: globalAgentDir, PK_PASSWORD: 'invalid', @@ -106,14 +104,12 @@ describe('sessions', () => { }, globalAgentDir, )); - testBinUtils.expectProcessError( - exitCode, - stderr, + testBinUtils.expectProcessError(exitCode, stderr, [ new clientErrors.ErrorClientAuthDenied(), - ); + ]); // Token set ({ exitCode, stderr } = await testBinUtils.pkStdio( - ['agent', 'status'], + ['agent', 'status', '--format', 'json'], { PK_NODE_PATH: globalAgentDir, PK_PASSWORD: undefined, @@ -121,11 +117,9 @@ describe('sessions', () => { }, globalAgentDir, )); - testBinUtils.expectProcessError( - exitCode, - stderr, + testBinUtils.expectProcessError(exitCode, stderr, [ new clientErrors.ErrorClientAuthDenied(), - ); + ]); }); test('prompt for password to authenticate attended commands', async () => { const password = globalAgentPassword; diff --git a/tests/bin/utils.retryAuthentication.test.ts b/tests/bin/utils.retryAuthentication.test.ts index 9a97f050f..32e45eee3 100644 --- a/tests/bin/utils.retryAuthentication.test.ts +++ b/tests/bin/utils.retryAuthentication.test.ts @@ -1,5 +1,5 @@ import prompts from 'prompts'; -import { mocked } from 'ts-jest/utils'; +import { mocked } from 'jest-mock'; import mockedEnv from 'mocked-env'; import { utils as clientUtils, errors as clientErrors } from '@/client'; import * as binUtils from '@/bin/utils'; diff --git a/tests/bin/utils.test.ts b/tests/bin/utils.test.ts index 42661b0af..45e6bd870 100644 --- a/tests/bin/utils.test.ts +++ b/tests/bin/utils.test.ts @@ -1,4 +1,8 @@ -import * as binUtils from '@/bin/utils'; +import type { Host, Port } from '@/network/types'; +import * as binUtils from '@/bin/utils/utils'; +import * as nodesUtils from '@/nodes/utils'; +import * as errors from '@/errors'; +import * as testUtils from '../utils'; describe('bin/utils', () => { test('list in human and json format', () => { @@ -70,4 +74,112 @@ describe('bin/utils', () => { }), ).toBe('{"key1":"value1","key2":"value2"}\n'); }); + test('errors in human and json format', () => { + const timestamp = new Date(); + const data = { string: 'one', number: 1 }; + const host = '127.0.0.1' as Host; + const port = 55555 as Port; + const nodeId = testUtils.generateRandomNodeId(); + const standardError = new TypeError('some error'); + const pkError = new errors.ErrorPolykey('some pk error', { + timestamp, + data, + }); + const remoteError = new errors.ErrorPolykeyRemote( + { + nodeId, + host, + port, + command: 'some command', + }, + 'some remote error', + { timestamp, cause: pkError }, + ); + const twoRemoteErrors = new errors.ErrorPolykeyRemote( + { + nodeId, + host, + port, + command: 'command 2', + }, + 'remote error', + { + timestamp, + cause: new errors.ErrorPolykeyRemote( + { + nodeId, + host, + port, + command: 'command 1', + }, + undefined, + { + timestamp, + cause: new errors.ErrorPolykey('pk error', { + timestamp, + cause: standardError, + }), + }, + ), + }, + ); + // Error + expect( + binUtils.outputFormatter({ type: 'error', data: standardError }), + ).toBe(`${standardError.name}: ${standardError.message}\n`); + expect(binUtils.outputFormatter({ type: 'error', data: pkError })).toBe( + `${pkError.name}: ${pkError.description} - ${pkError.message}\n` + + ` exitCode\t${pkError.exitCode}\n` + + ` timestamp\t${timestamp.toString()}\n` + + ` data\t${JSON.stringify(data)}\n`, + ); + expect(binUtils.outputFormatter({ type: 'error', data: remoteError })).toBe( + `${remoteError.name}: ${remoteError.description} - ${remoteError.message}\n` + + ` command\t${remoteError.metadata.command}\n` + + ` nodeId\t${nodesUtils.encodeNodeId(nodeId)}\n` + + ` host\t${host}\n` + + ` port\t${port}\n` + + ` timestamp\t${timestamp.toString()}\n` + + ` remote error: ${remoteError.cause.name}: ${remoteError.cause.description} - ${remoteError.cause.message}\n` + + ` exitCode\t${pkError.exitCode}\n` + + ` timestamp\t${timestamp.toString()}\n` + + ` data\t${JSON.stringify(data)}\n`, + ); + expect( + binUtils.outputFormatter({ type: 'error', data: twoRemoteErrors }), + ).toBe( + `${twoRemoteErrors.name}: ${twoRemoteErrors.description} - ${twoRemoteErrors.message}\n` + + ` command\t${twoRemoteErrors.metadata.command}\n` + + ` nodeId\t${nodesUtils.encodeNodeId(nodeId)}\n` + + ` host\t${host}\n` + + ` port\t${port}\n` + + ` timestamp\t${timestamp.toString()}\n` + + ` remote error: ${twoRemoteErrors.cause.name}: ${twoRemoteErrors.cause.description}\n` + + ` command\t${twoRemoteErrors.cause.metadata.command}\n` + + ` nodeId\t${nodesUtils.encodeNodeId(nodeId)}\n` + + ` host\t${host}\n` + + ` port\t${port}\n` + + ` timestamp\t${timestamp.toString()}\n` + + ` remote error: ${twoRemoteErrors.cause.cause.name}: ${twoRemoteErrors.cause.cause.description} - ${twoRemoteErrors.cause.cause.message}\n` + + ` exitCode\t${pkError.exitCode}\n` + + ` timestamp\t${timestamp.toString()}\n` + + ` cause: ${standardError.name}: ${standardError.message}\n`, + ); + expect( + binUtils.outputFormatter({ type: 'json', data: standardError }), + ).toBe( + `{"type":"${standardError.name}","data":{"message":"${ + standardError.message + }","stack":"${standardError.stack?.replaceAll('\n', '\\n')}"}}\n`, + ); + expect(binUtils.outputFormatter({ type: 'json', data: pkError })).toBe( + JSON.stringify(pkError.toJSON()) + '\n', + ); + expect(binUtils.outputFormatter({ type: 'json', data: remoteError })).toBe( + JSON.stringify(remoteError.toJSON()) + '\n', + ); + expect( + binUtils.outputFormatter({ type: 'json', data: twoRemoteErrors }), + ).toBe(JSON.stringify(twoRemoteErrors.toJSON()) + '\n'); + }); }); diff --git a/tests/bin/utils.ts b/tests/bin/utils.ts index 3b552cf64..2464b9d82 100644 --- a/tests/bin/utils.ts +++ b/tests/bin/utils.ts @@ -12,6 +12,7 @@ import nexpect from 'nexpect'; import Logger from '@matrixai/logger'; import main from '@/bin/polykey'; import * as binUtils from '@/bin/utils'; +import * as grpcUtils from '@/grpc/utils'; /** * Runs pk command functionally @@ -339,23 +340,24 @@ async function processExit( /** * Checks exit code and stderr against ErrorPolykey + * Errors should contain all of the errors in the expected error chain + * starting with the outermost error (excluding ErrorPolykeyRemote) + * When using this function, the command must be run with --format=json */ function expectProcessError( exitCode: number, stderr: string, - error: ErrorPolykey, + errors: Array>, ) { - expect(exitCode).toBe(error.exitCode); + expect(exitCode).toBe(errors[0].exitCode); const stdErrLine = stderr.trim().split('\n').pop(); - const errorOutput = binUtils - .outputFormatter({ - type: 'error', - name: error.name, - description: error.description, - message: error.message, - }) - .trim(); - expect(stdErrLine).toBe(errorOutput); + const receivedError = JSON.parse(stdErrLine!, grpcUtils.reviver); + let [currentError] = binUtils.remoteErrorCause(receivedError); + for (const error of errors) { + expect(currentError.name).toBe(error.name); + expect(currentError.message).toBe(error.message); + currentError = currentError.cause; + } } export { From cc801b6ceeaae57eb1965201f860891f9c8c96d0 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 18 May 2022 16:17:37 +1000 Subject: [PATCH 47/74] tests: fixing bin tests Had to fix `expectProcessError` to work with the raw JSON forms of the errors rather than attempting to parse the errors. This is due to the bin CLI errors being separate from the normal errors and the reviver being unable to revive them. I also had to fix how the `ErrorPolykeyRemote` converted the metadata with toJSON/fromJSON. --- src/PolykeyAgent.ts | 2 + src/bin/nodes/CommandFind.ts | 4 +- src/bin/nodes/CommandPing.ts | 2 +- src/client/service/agentLockAll.ts | 1 - .../service/gestaltsActionsGetByIdentity.ts | 6 +- src/errors.ts | 12 +++- tests/agent/GRPCClientAgent.test.ts | 1 + tests/agent/utils.ts | 6 +- tests/bin/agent/lock.test.ts | 2 +- tests/bin/identities/claim.test.ts | 2 +- tests/bin/identities/trustUntrustList.test.ts | 49 ++------------ tests/bin/nodes/find.test.ts | 3 +- tests/bin/nodes/ping.test.ts | 3 +- tests/bin/utils.ts | 16 ++--- tests/client/rpcVaults.test.ts | 1 + ...staltsActionsSetUnsetGetByIdentity.test.ts | 1 + tests/nodes/NodeConnection.test.ts | 66 ++++++++----------- 17 files changed, 74 insertions(+), 103 deletions(-) diff --git a/src/PolykeyAgent.ts b/src/PolykeyAgent.ts index b172f1fd2..68e3b5571 100644 --- a/src/PolykeyAgent.ts +++ b/src/PolykeyAgent.ts @@ -560,6 +560,7 @@ class PolykeyAgent { acl: this.acl, gestaltGraph: this.gestaltGraph, proxy: this.proxy, + logger: this.logger.getChild(createAgentService.name), }); const clientService = createClientService({ pkAgent: this, @@ -580,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/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 3ff6049a1..a15779c55 100644 --- a/src/bin/nodes/CommandPing.ts +++ b/src/bin/nodes/CommandPing.ts @@ -55,7 +55,7 @@ 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, diff --git a/src/client/service/agentLockAll.ts b/src/client/service/agentLockAll.ts index f1d4c4d03..1bc011b08 100644 --- a/src/client/service/agentLockAll.ts +++ b/src/client/service/agentLockAll.ts @@ -3,7 +3,6 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { SessionManager } from '../../sessions'; import type Logger from '@matrixai/logger'; -import { withF } from '@matrixai/resources'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; diff --git a/src/client/service/gestaltsActionsGetByIdentity.ts b/src/client/service/gestaltsActionsGetByIdentity.ts index 14da28205..a1ee40c4a 100644 --- a/src/client/service/gestaltsActionsGetByIdentity.ts +++ b/src/client/service/gestaltsActionsGetByIdentity.ts @@ -47,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 diff --git a/src/errors.ts b/src/errors.ts index 139744171..12af747ab 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -2,6 +2,7 @@ import type { Class } from '@matrixai/errors'; import type { ClientMetadata } from './types'; import ErrorPolykey from './ErrorPolykey'; import sysexits from './utils/sysexits'; +import * as nodesUtils from './nodes/utils'; class ErrorPolykeyRemote extends ErrorPolykey { static description = 'Remote error from RPC call'; @@ -30,7 +31,11 @@ class ErrorPolykeyRemote extends ErrorPolykey { ) { throw new TypeError(`Cannot decode JSON to ${this.name}`); } - const e = new this(json.data.metadata, json.data.message, { + const parsedMetadata: ClientMetadata = { + ...json.data.metadata, + nodeId: nodesUtils.decodeNodeId(json.data.metadata.nodeId), + }; + const e = new this(parsedMetadata, json.data.message, { timestamp: new Date(json.data.timestamp), data: json.data.data, cause: json.data.cause, @@ -42,7 +47,10 @@ class ErrorPolykeyRemote extends ErrorPolykey { public toJSON(): any { const json = super.toJSON(); - json.data.metadata = this.metadata; + json.data.metadata = { + ...this.metadata, + nodeId: nodesUtils.encodeNodeId(this.metadata.nodeId), + }; return json; } } diff --git a/tests/agent/GRPCClientAgent.test.ts b/tests/agent/GRPCClientAgent.test.ts index 2a9392e74..60a84410c 100644 --- a/tests/agent/GRPCClientAgent.test.ts +++ b/tests/agent/GRPCClientAgent.test.ts @@ -157,6 +157,7 @@ describe(GRPCClientAgent.name, () => { gestaltGraph, proxy, db, + logger, }); client = await testAgentUtils.openTestAgentClient(port); await proxy.start({ diff --git a/tests/agent/utils.ts b/tests/agent/utils.ts index 296707684..f2b896024 100644 --- a/tests/agent/utils.ts +++ b/tests/agent/utils.ts @@ -11,6 +11,7 @@ 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'; @@ -33,6 +34,7 @@ async function openTestAgentServer({ gestaltGraph, proxy, db, + logger, }: { keyManager: KeyManager; vaultManager: VaultManager; @@ -45,7 +47,8 @@ async function openTestAgentServer({ gestaltGraph: GestaltGraph; proxy: Proxy; db: DB; -}) { + logger: Logger; +}): Promise<[Server, Port]> { const agentService: IAgentServiceServer = createAgentService({ keyManager, vaultManager, @@ -58,6 +61,7 @@ async function openTestAgentServer({ gestaltGraph, proxy, db, + logger, }); const server = new grpc.Server(); diff --git a/tests/bin/agent/lock.test.ts b/tests/bin/agent/lock.test.ts index a35719991..f12a7fc89 100644 --- a/tests/bin/agent/lock.test.ts +++ b/tests/bin/agent/lock.test.ts @@ -48,7 +48,7 @@ describe('lock', () => { expect(await session.readToken()).toBeUndefined(); await session.stop(); }); - test('lock ensures reauthentication is required', async () => { + test('lock ensures re-authentication is required', async () => { const password = globalAgentPassword; mockedPrompts.mockClear(); mockedPrompts.mockImplementation(async (_opts: any) => { 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 2464b9d82..b0acefed2 100644 --- a/tests/bin/utils.ts +++ b/tests/bin/utils.ts @@ -1,18 +1,16 @@ import type { ChildProcess } from 'child_process'; import type ErrorPolykey from '@/ErrorPolykey'; +import child_process from 'child_process'; import os from 'os'; import fs from 'fs'; import path from 'path'; import process from 'process'; -import child_process from 'child_process'; import readline from 'readline'; import * as mockProcess from 'jest-mock-process'; import mockedEnv from 'mocked-env'; import nexpect from 'nexpect'; import Logger from '@matrixai/logger'; import main from '@/bin/polykey'; -import * as binUtils from '@/bin/utils'; -import * as grpcUtils from '@/grpc/utils'; /** * Runs pk command functionally @@ -351,12 +349,14 @@ function expectProcessError( ) { expect(exitCode).toBe(errors[0].exitCode); const stdErrLine = stderr.trim().split('\n').pop(); - const receivedError = JSON.parse(stdErrLine!, grpcUtils.reviver); - let [currentError] = binUtils.remoteErrorCause(receivedError); + let currentError = JSON.parse(stdErrLine!); + while (currentError.type === 'ErrorPolykeyRemote') { + currentError = currentError.data.cause; + } for (const error of errors) { - expect(currentError.name).toBe(error.name); - expect(currentError.message).toBe(error.message); - currentError = currentError.cause; + expect(currentError.type).toBe(error.name); + expect(currentError.data.message).toBe(error.message); + currentError = currentError.data.cause; } } diff --git a/tests/client/rpcVaults.test.ts b/tests/client/rpcVaults.test.ts index 98f4b80af..22b9cb1c9 100644 --- a/tests/client/rpcVaults.test.ts +++ b/tests/client/rpcVaults.test.ts @@ -118,6 +118,7 @@ describe('Vaults client service', () => { test('should get vaults', async () => { const listVaults = grpcUtils.promisifyReadableStreamCall( client, + nodeId, localHost, localPort, client.vaultsList, diff --git a/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts b/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts index f20373610..381ec9b60 100644 --- a/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts +++ b/tests/client/service/gestaltsActionsSetUnsetGetByIdentity.test.ts @@ -79,6 +79,7 @@ describe('gestaltsActionsByIdentity', () => { authenticate, gestaltGraph, logger, + db, }), gestaltsActionsUnsetByIdentity: gestaltsActionsUnsetByIdentity({ authenticate, diff --git a/tests/nodes/NodeConnection.test.ts b/tests/nodes/NodeConnection.test.ts index fcc37d701..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,7 @@ describe(`${NodeConnection.name} test`, () => { logger: logger, }); await serverGestaltGraph.setNode(node); - const agentService = createAgentService({ + [agentServer, serverPort] = await agentTestUtils.openTestAgentServer({ db: serverDb, keyManager: serverKeyManager, vaultManager: serverVaultManager, @@ -278,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, }); @@ -312,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(); @@ -340,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, { @@ -361,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(); @@ -379,7 +373,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -395,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 () => { @@ -403,7 +397,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -419,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(); @@ -435,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, @@ -444,7 +437,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -460,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(); @@ -491,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, @@ -526,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, @@ -542,7 +534,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -563,7 +555,7 @@ describe(`${NodeConnection.name} test`, () => { targetNodeId: targetNodeId, targetHost: localHost, targetPort: targetPort, - proxy: clientproxy, + proxy: clientProxy, keyManager: clientKeyManager, nodeConnectionManager: dummyNodeConnectionManager, destroyCallback, @@ -601,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, @@ -644,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, @@ -682,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, @@ -744,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, @@ -813,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, From c3a7fd29701cbcfa8df31fc7f6b7ba8c71341996 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 24 May 2022 13:35:51 +1000 Subject: [PATCH 48/74] fix: added logic check to `NotificationsManager.readNotifications` There was a bug with the DB that is getting fixed. This just throws a clear error when a notification can't be read despite it being in the list of all notifications. --- src/notifications/NotificationsManager.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/notifications/NotificationsManager.ts b/src/notifications/NotificationsManager.ts index b2780000a..dce39dd16 100644 --- a/src/notifications/NotificationsManager.ts +++ b/src/notifications/NotificationsManager.ts @@ -23,6 +23,7 @@ import * as notificationsUtils from './utils'; import * as notificationsErrors from './errors'; import * as notificationsPB from '../proto/js/polykey/v1/notifications/notifications_pb'; import * as nodesUtils from '../nodes/utils'; +import { never } from '../utils/utils'; const MESSAGE_COUNT_KEY = 'numMessages'; @@ -289,7 +290,8 @@ class NotificationsManager { const notifications: Array = []; for (const id of notificationIds) { const notification = await this.readNotificationById(id, tran); - notifications.push(notification!); + if (notification == null) never(); + notifications.push(notification); } return notifications; From 6d7105e9d394aff3f86f97cf585e56263144579c Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Tue, 24 May 2022 13:45:34 +1000 Subject: [PATCH 49/74] tests: split vaults client service tests --- src/grpc/utils/utils.ts | 2 +- tests/client/rpcVaults.test.ts | 372 +----------------- tests/client/service/vaultsClone.test.ts | 99 +++++ .../service/vaultsCreateDeleteList.test.ts | 168 ++++++++ tests/client/service/vaultsLog.test.ts | 188 +++++++++ .../vaultsPermissionSetUnsetGet.test.ts | 226 +++++++++++ tests/client/service/vaultsPull.test.ts | 99 +++++ tests/client/service/vaultsRename.test.ts | 128 ++++++ tests/client/service/vaultsScan.test.ts | 91 +++++ tests/client/service/vaultsVersion.test.ts | 182 +++++++++ 10 files changed, 1184 insertions(+), 371 deletions(-) create mode 100644 tests/client/service/vaultsClone.test.ts create mode 100644 tests/client/service/vaultsCreateDeleteList.test.ts create mode 100644 tests/client/service/vaultsLog.test.ts create mode 100644 tests/client/service/vaultsPermissionSetUnsetGet.test.ts create mode 100644 tests/client/service/vaultsPull.test.ts create mode 100644 tests/client/service/vaultsRename.test.ts create mode 100644 tests/client/service/vaultsScan.test.ts create mode 100644 tests/client/service/vaultsVersion.test.ts diff --git a/src/grpc/utils/utils.ts b/src/grpc/utils/utils.ts index f37442e41..1b98d310f 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -188,7 +188,7 @@ function toError( e: ServiceError, metadata: ClientMetadata, ): errors.ErrorPolykey { - const errorData = e.metadata.get('error')[0].toString(); + const errorData = e.metadata.get('error')[0] as string; // Grpc.status is an enum // this will iterate the enum values then enum keys // they will all be of string type diff --git a/tests/client/rpcVaults.test.ts b/tests/client/rpcVaults.test.ts index 22b9cb1c9..0d0ccc6d7 100644 --- a/tests/client/rpcVaults.test.ts +++ b/tests/client/rpcVaults.test.ts @@ -1,9 +1,9 @@ import type * as grpc from '@grpc/grpc-js'; import type VaultManager from '@/vaults/VaultManager'; -import type { VaultId, VaultName } from '@/vaults/types'; +import type { 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 type * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import os from 'os'; import path from 'path'; import fs from 'fs'; @@ -11,16 +11,12 @@ import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; 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 * 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'), @@ -40,8 +36,6 @@ 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; @@ -113,368 +107,6 @@ describe('Vaults client service', () => { await vaultManager.destroyVault(vaultId); } }); - - describe('Vaults', () => { - test('should get vaults', async () => { - const listVaults = grpcUtils.promisifyReadableStreamCall( - client, - nodeId, - localHost, - localPort, - client.vaultsList, - ); - for (const vaultName of vaultList) { - await vaultManager.createVault(vaultName); - } - const emptyMessage = new utilsPB.EmptyMessage(); - const vaultStream = listVaults(emptyMessage, callCredentials); - const names: Array = []; - for await (const vault of vaultStream) { - names.push(vault.getVaultName()); - } - expect(names.sort()).toStrictEqual(vaultList.sort()); - }); - test('should create vault', async () => { - const createVault = grpcUtils.promisifyUnaryCall( - client, - client.vaultsCreate, - ); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultList[0]); - const vaultId = await createVault(vaultMessage, callCredentials); - const vaultNames = await vaultManager.listVaults(); - expect(vaultNames.get(vaultList[0])).toBeTruthy(); - expect( - vaultsUtils.encodeVaultId(vaultNames.get(vaultList[0])!), - ).toStrictEqual(vaultId.getNameOrId()); - }); - test('should delete vaults', async () => { - const deleteVault = grpcUtils.promisifyUnaryCall( - client, - client.vaultsDelete, - ); - for (const vaultName of vaultList) { - await vaultManager.createVault(vaultName); - } - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultList[0]); - await deleteVault(vaultMessage, callCredentials); - const listVaults = await vaultManager.listVaults(); - const modifiedVaultList: string[] = []; - for (const [vaultName] of listVaults) { - modifiedVaultList.push(vaultName); - } - expect(modifiedVaultList.sort()).toStrictEqual(vaultList.slice(1).sort()); - }); - test('should rename vaults', async () => { - const renameVault = grpcUtils.promisifyUnaryCall( - client, - client.vaultsRename, - ); - const vaultId1 = await vaultManager.createVault(vaultList[0]); - - const vaultRenameMessage = new vaultsPB.Rename(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId1)); - vaultRenameMessage.setVault(vaultMessage); - vaultRenameMessage.setNewName(vaultList[1]); - - const vaultId2 = await renameVault(vaultRenameMessage, callCredentials); - expect(vaultsUtils.decodeVaultId(vaultId2.getNameOrId())).toStrictEqual( - vaultId1, - ); - - const renamedVaultId = await vaultManager.getVaultId(vaultList[1]); - expect(renamedVaultId).toEqual(vaultId1); - }); - describe('Version', () => { - const secretVer1 = { - name: secretList[0], - content: 'Secret-1-content-ver1', - }; - const secretVer2 = { - name: secretList[0], - content: 'Secret-1-content-ver2', - }; - let vaultId: VaultId; - let vaultsVersion; - - beforeEach(async () => { - vaultId = await vaultManager.createVault(vaultList[0]); - vaultsVersion = grpcUtils.promisifyUnaryCall( - client, - client.vaultsVersion, - ); - }); - - test('should switch a vault to a version', async () => { - // Commit some history - const ver1Oid = await vaultManager.withVaults( - [vaultId], - async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile(secretVer1.name, secretVer1.content); - }); - const ver1Oid = (await vault.log())[0].commitId; - await vault.writeF(async (efs) => { - await efs.writeFile(secretVer2.name, secretVer2.content); - }); - return ver1Oid; - }, - ); - - // Revert the version - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultList[0]); - - const vaultVersionMessage = new vaultsPB.Version(); - vaultVersionMessage.setVault(vaultMessage); - vaultVersionMessage.setVersionId(ver1Oid); - - const version = await vaultsVersion( - vaultVersionMessage, - callCredentials, - ); - expect(version.getIsLatestVersion()).toBeFalsy(); - // Read old history - - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.readF(async (efs) => { - expect( - (await efs.readFile(secretVer1.name)).toString(), - ).toStrictEqual(secretVer1.content); - }); - }); - }); - test('should fail to find a non existent version', async () => { - // Revert the version - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - const vaultVersionMessage = new vaultsPB.Version(); - vaultVersionMessage.setVault(vaultMessage); - vaultVersionMessage.setVersionId('invalidOid'); - const version = vaultsVersion(vaultVersionMessage, callCredentials); - await expectRemoteError( - version, - vaultErrors.ErrorVaultReferenceInvalid, - ); - - vaultVersionMessage.setVersionId( - '7660aa9a2fee90e875c2d19e5deefe882ca1d4d9', - ); - const version2 = vaultsVersion(vaultVersionMessage, callCredentials); - await expectRemoteError( - version2, - vaultErrors.ErrorVaultReferenceMissing, - ); - }); - }); - describe('Vault Log', () => { - let vaultLog; - const secret1 = { name: secretList[0], content: 'Secret-1-content' }; - const secret2 = { name: secretList[1], content: 'Secret-2-content' }; - let vaultId: VaultId; - let commit1Oid: string; - let commit2Oid: string; - let commit3Oid: string; - - beforeEach(async () => { - vaultLog = grpcUtils.promisifyReadableStreamCall( - client, - client.vaultsLog, - ); - vaultId = await vaultManager.createVault(vaultList[0]); - - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile(secret1.name, secret1.content); - }); - commit1Oid = (await vault.log(undefined, 0))[0].commitId; - - await vault.writeF(async (efs) => { - await efs.writeFile(secret2.name, secret2.content); - }); - commit2Oid = (await vault.log(undefined, 0))[0].commitId; - - await vault.writeF(async (efs) => { - await efs.unlink(secret2.name); - }); - commit3Oid = (await vault.log(undefined, 0))[0].commitId; - }); - }); - - test('should get the full log', async () => { - const vaultLog = - grpcUtils.promisifyReadableStreamCall( - client, - client.vaultsLog, - ); - const vaultsLogMessage = new vaultsPB.Log(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultList[0]); - vaultsLogMessage.setVault(vaultMessage); - const logStream = vaultLog(vaultsLogMessage, callCredentials); - const logMessages: vaultsPB.LogEntry[] = []; - for await (const log of logStream) { - logMessages.push(log); - } - // Checking commits exist in order. - expect(logMessages[2].getOid()).toEqual(commit1Oid); - expect(logMessages[1].getOid()).toEqual(commit2Oid); - expect(logMessages[0].getOid()).toEqual(commit3Oid); - }); - test('should get a part of the log', async () => { - const vaultsLogMessage = new vaultsPB.Log(); - const vaultMessage = new vaultsPB.Vault(); - - vaultMessage.setNameOrId(vaultList[0]); - vaultsLogMessage.setVault(vaultMessage); - vaultsLogMessage.setLogDepth(2); - - const logStream = await vaultLog(vaultsLogMessage, callCredentials); - const logMessages: vaultsPB.LogEntry[] = []; - for await (const log of logStream) { - logMessages.push(log); - } - - // Checking commits exist in order. - expect(logMessages[1].getOid()).toEqual(commit2Oid); - expect(logMessages[0].getOid()).toEqual(commit3Oid); - }); - test('should get a specific commit', async () => { - const vaultsLogMessage = new vaultsPB.Log(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultList[0]); - vaultsLogMessage.setVault(vaultMessage); - vaultsLogMessage.setCommitId(commit2Oid); - const logStream = await vaultLog(vaultsLogMessage, callCredentials); - const logMessages: vaultsPB.LogEntry[] = []; - for await (const log of logStream) { - logMessages.push(log); - } - // Checking commits exist in order. - expect(logMessages[0].getOid()).toEqual(commit2Oid); - }); - }); - test('should get vault permissions', async () => { - const vaultsPermissionsGet = - grpcUtils.promisifyReadableStreamCall( - client, - client.vaultsPermissionGet, - ); - - let remoteKeynode1: PolykeyAgent | undefined; - let remoteKeynode2: PolykeyAgent | undefined; - try { - remoteKeynode1 = await PolykeyAgent.createPolykeyAgent({ - password, - logger: logger.getChild('Remote Keynode 1'), - nodePath: path.join(dataDir, 'remoteKeynode1'), - }); - remoteKeynode2 = await PolykeyAgent.createPolykeyAgent({ - password, - logger: logger.getChild('Remote Keynode 2'), - nodePath: path.join(dataDir, 'remoteKeynode2'), - }); - const targetNodeId1 = remoteKeynode1.keyManager.getNodeId(); - const targetNodeId2 = remoteKeynode2.keyManager.getNodeId(); - const pkAgentNodeId = pkAgent.keyManager.getNodeId(); - await pkAgent.gestaltGraph.setNode({ - id: nodesUtils.encodeNodeId(targetNodeId1), - chain: {}, - }); - await pkAgent.gestaltGraph.setNode({ - id: nodesUtils.encodeNodeId(targetNodeId2), - chain: {}, - }); - - await pkAgent.nodeManager.setNode(targetNodeId1, { - host: remoteKeynode1.proxy.getProxyHost(), - port: remoteKeynode1.proxy.getProxyPort(), - }); - await pkAgent.nodeManager.setNode(targetNodeId2, { - host: remoteKeynode2.proxy.getProxyHost(), - port: remoteKeynode2.proxy.getProxyPort(), - }); - - await remoteKeynode1.nodeManager.setNode(pkAgentNodeId, { - host: pkAgent.proxy.getProxyHost(), - port: pkAgent.proxy.getProxyPort(), - }); - await remoteKeynode2.nodeManager.setNode(pkAgentNodeId, { - host: pkAgent.proxy.getProxyHost(), - port: pkAgent.proxy.getProxyPort(), - }); - await remoteKeynode1.acl.setNodePerm(pkAgentNodeId, { - gestalt: { - notify: null, - }, - vaults: {}, - }); - await remoteKeynode2.acl.setNodePerm(pkAgentNodeId, { - gestalt: { - notify: null, - }, - vaults: {}, - }); - - const vaultId1 = await vaultManager.createVault(vaultList[0]); - const vaultId2 = await vaultManager.createVault(vaultList[1]); - - await pkAgent.gestaltGraph.setGestaltActionByNode( - targetNodeId1, - 'scan', - ); - await pkAgent.acl.setVaultAction(vaultId1, targetNodeId1, 'clone'); - await pkAgent.acl.setVaultAction(vaultId1, targetNodeId1, 'pull'); - await pkAgent.gestaltGraph.setGestaltActionByNode( - targetNodeId2, - 'scan', - ); - await pkAgent.acl.setVaultAction(vaultId1, targetNodeId2, 'clone'); - await pkAgent.acl.setVaultAction(vaultId1, targetNodeId2, 'pull'); - await pkAgent.gestaltGraph.setGestaltActionByNode( - targetNodeId1, - 'scan', - ); - await pkAgent.acl.setVaultAction(vaultId2, targetNodeId1, 'clone'); - await pkAgent.acl.setVaultAction(vaultId2, targetNodeId1, 'pull'); - - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId1)); - - const permissionsStream = vaultsPermissionsGet( - vaultMessage, - callCredentials, - ); - const list: Record[] = []; - for await (const permission of permissionsStream) { - const permissionsList = permission.getVaultPermissionsList(); - expect(permissionsList).toContain('pull'); - expect(permissionsList).toContain('clone'); - list.push(permission.toObject()); - } - expect(list).toHaveLength(2); - - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId2)); - const permissionStream2 = vaultsPermissionsGet( - vaultMessage, - callCredentials, - ); - for await (const permission of permissionStream2) { - const permissionsList = permission.getVaultPermissionsList(); - expect(permissionsList).toContain('pull'); - expect(permissionsList).toContain('clone'); - const node = permission.getNode(); - const nodeId = node?.getNodeId(); - expect(nodeId).toEqual(nodesUtils.encodeNodeId(targetNodeId1)); - } - } finally { - await remoteKeynode1?.stop(); - await remoteKeynode2?.stop(); - } - }); - }); describe('Secrets', () => { test('should make a directory in a vault', async () => { const mkdirVault = grpcUtils.promisifyUnaryCall( diff --git a/tests/client/service/vaultsClone.test.ts b/tests/client/service/vaultsClone.test.ts new file mode 100644 index 000000000..b54f629db --- /dev/null +++ b/tests/client/service/vaultsClone.test.ts @@ -0,0 +1,99 @@ +import type { Host, Port } from '@/network/types'; +import type KeyManager from '@/keys/KeyManager'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsClone from '@/client/service/vaultsClone'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsClone', () => { + const logger = new Logger('vaultsClone test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager: {} as KeyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsClone: vaultsClone({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test.todo('clones a vault'); +}); diff --git a/tests/client/service/vaultsCreateDeleteList.test.ts b/tests/client/service/vaultsCreateDeleteList.test.ts new file mode 100644 index 000000000..c04644056 --- /dev/null +++ b/tests/client/service/vaultsCreateDeleteList.test.ts @@ -0,0 +1,168 @@ +import type { Host, Port } from '@/network/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsCreate from '@/client/service/vaultsCreate'; +import vaultsDelete from '@/client/service/vaultsDelete'; +import vaultsList from '@/client/service/vaultsList'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsCreateDeleteList', () => { + const logger = new Logger('vaultsCreateDeleteList test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsCreate: vaultsCreate({ + authenticate, + vaultManager, + db, + logger, + }), + vaultsDelete: vaultsDelete({ + authenticate, + vaultManager, + db, + logger, + }), + vaultsList: vaultsList({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('creates, lists, and deletes vaults', async () => { + // Create vault + const createRequest = new vaultsPB.Vault(); + createRequest.setNameOrId('test-vault'); + const createResponse = await grpcClient.vaultsCreate( + createRequest, + clientUtils.encodeAuthFromPassword(password), + ); + expect(createResponse).toBeInstanceOf(vaultsPB.Vault); + const vaultId = createResponse.getNameOrId(); + // List vault + const emptyMessage = new utilsPB.EmptyMessage(); + const listResponse1 = grpcClient.vaultsList( + emptyMessage, + clientUtils.encodeAuthFromPassword(password), + ); + const vaults1: Array<{ name: string; id: string }> = []; + for await (const vault of listResponse1) { + expect(vault).toBeInstanceOf(vaultsPB.List); + vaults1.push({ name: vault.getVaultName(), id: vault.getVaultId() }); + } + expect(vaults1).toHaveLength(1); + expect(vaults1[0].name).toBe('test-vault'); + expect(vaults1[0].id).toBe(vaultId); + // Delete vault + const deleteRequest = createRequest; + const deleteResponse = await grpcClient.vaultsDelete( + deleteRequest, + clientUtils.encodeAuthFromPassword(password), + ); + expect(deleteResponse).toBeInstanceOf(utilsPB.StatusMessage); + expect(deleteResponse.getSuccess()).toBeTruthy(); + // Check vault was deleted + const listResponse2 = grpcClient.vaultsList( + emptyMessage, + clientUtils.encodeAuthFromPassword(password), + ); + const vaults2: Array<{ name: string; id: string }> = []; + for await (const vault of listResponse2) { + expect(vault).toBeInstanceOf(vaultsPB.List); + vaults2.push({ name: vault.getVaultName(), id: vault.getVaultId() }); + } + expect(vaults2).toHaveLength(0); + }); +}); diff --git a/tests/client/service/vaultsLog.test.ts b/tests/client/service/vaultsLog.test.ts new file mode 100644 index 000000000..d2f5ed26d --- /dev/null +++ b/tests/client/service/vaultsLog.test.ts @@ -0,0 +1,188 @@ +import type { Host, Port } from '@/network/types'; +import type { VaultId } from '@/vaults/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsLog from '@/client/service/vaultsLog'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsLog', () => { + const logger = new Logger('vaultsLog test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + const vaultName = 'test-vault'; + const secret1 = { name: 'secret1', content: 'Secret-1-content' }; + const secret2 = { name: 'secret2', content: 'Secret-2-content' }; + let dataDir: string; + let vaultId: VaultId; + let commit1Oid: string; + let commit2Oid: string; + let commit3Oid: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + vaultId = await vaultManager.createVault(vaultName); + await vaultManager.withVaults([vaultId], async (vault) => { + await vault.writeF(async (efs) => { + await efs.writeFile(secret1.name, secret1.content); + }); + commit1Oid = (await vault.log(undefined, 0))[0].commitId; + await vault.writeF(async (efs) => { + await efs.writeFile(secret2.name, secret2.content); + }); + commit2Oid = (await vault.log(undefined, 0))[0].commitId; + await vault.writeF(async (efs) => { + await efs.unlink(secret2.name); + }); + commit3Oid = (await vault.log(undefined, 0))[0].commitId; + }); + const clientService = { + vaultsLog: vaultsLog({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('should get the full log', async () => { + const vaultsLogMessage = new vaultsPB.Log(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultName); + vaultsLogMessage.setVault(vaultMessage); + const logStream = grpcClient.vaultsLog( + vaultsLogMessage, + clientUtils.encodeAuthFromPassword(password), + ); + const logMessages: vaultsPB.LogEntry[] = []; + for await (const log of logStream) { + expect(log).toBeInstanceOf(vaultsPB.LogEntry); + logMessages.push(log); + } + // Checking commits exist in order. + expect(logMessages[2].getOid()).toEqual(commit1Oid); + expect(logMessages[1].getOid()).toEqual(commit2Oid); + expect(logMessages[0].getOid()).toEqual(commit3Oid); + }); + test('should get a part of the log', async () => { + const vaultsLogMessage = new vaultsPB.Log(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultName); + vaultsLogMessage.setVault(vaultMessage); + vaultsLogMessage.setLogDepth(2); + const logStream = grpcClient.vaultsLog( + vaultsLogMessage, + clientUtils.encodeAuthFromPassword(password), + ); + const logMessages: vaultsPB.LogEntry[] = []; + for await (const log of logStream) { + expect(log).toBeInstanceOf(vaultsPB.LogEntry); + logMessages.push(log); + } + // Checking commits exist in order. + expect(logMessages[1].getOid()).toEqual(commit2Oid); + expect(logMessages[0].getOid()).toEqual(commit3Oid); + }); + test('should get a specific commit', async () => { + const vaultsLogMessage = new vaultsPB.Log(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultName); + vaultsLogMessage.setVault(vaultMessage); + vaultsLogMessage.setCommitId(commit2Oid); + const logStream = grpcClient.vaultsLog( + vaultsLogMessage, + clientUtils.encodeAuthFromPassword(password), + ); + const logMessages: vaultsPB.LogEntry[] = []; + for await (const log of logStream) { + expect(log).toBeInstanceOf(vaultsPB.LogEntry); + logMessages.push(log); + } + // Checking commits exist in order. + expect(logMessages[0].getOid()).toEqual(commit2Oid); + }); +}); diff --git a/tests/client/service/vaultsPermissionSetUnsetGet.test.ts b/tests/client/service/vaultsPermissionSetUnsetGet.test.ts new file mode 100644 index 000000000..299ab6219 --- /dev/null +++ b/tests/client/service/vaultsPermissionSetUnsetGet.test.ts @@ -0,0 +1,226 @@ +import type { Host, Port } from '@/network/types'; +import type NodeManager from '@/nodes/NodeManager'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +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 { Metadata } from '@grpc/grpc-js'; +import ACL from '@/acl/ACL'; +import GestaltGraph from '@/gestalts/GestaltGraph'; +import KeyManager from '@/keys/KeyManager'; +import NotificationsManager from '@/notifications/NotificationsManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsPermissionGet from '@/client/service/vaultsPermissionGet'; +import vaultsPermissionSet from '@/client/service/vaultsPermissionSet'; +import vaultsPermissionUnset from '@/client/service/vaultsPermissionUnset'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +import * as nodesPB from '@/proto/js/polykey/v1/nodes/nodes_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as keysUtils from '@/keys/utils'; +import * as nodesUtils from '@/nodes/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsPermissionSetUnsetGet', () => { + const logger = new Logger('vaultsPermissionSetUnsetGet test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + let mockedSendNotification: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + mockedSendNotification = jest + .spyOn(NotificationsManager.prototype, 'sendNotification') + .mockImplementation(); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + mockedSendNotification.mockRestore(); + }); + const nodeId = testUtils.generateRandomNodeId(); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let acl: ACL; + let gestaltGraph: GestaltGraph; + let notificationsManager: NotificationsManager; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + acl = await ACL.createACL({ + db, + logger, + }); + gestaltGraph = await GestaltGraph.createGestaltGraph({ + db, + acl, + logger, + }); + await gestaltGraph.setNode({ + id: nodesUtils.encodeNodeId(nodeId), + chain: {}, + }); + notificationsManager = + await NotificationsManager.createNotificationsManager({ + acl, + db, + nodeConnectionManager: {} as NodeConnectionManager, + nodeManager: {} as NodeManager, + keyManager, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph, + notificationsManager: notificationsManager, + logger, + }); + const clientService = { + vaultsPermissionSet: vaultsPermissionSet({ + authenticate, + vaultManager, + gestaltGraph, + acl, + notificationsManager, + db, + logger, + }), + vaultsPermissionUnset: vaultsPermissionUnset({ + authenticate, + vaultManager, + gestaltGraph, + acl, + db, + logger, + }), + vaultsPermissionGet: vaultsPermissionGet({ + authenticate, + vaultManager, + acl, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await notificationsManager.stop(); + await gestaltGraph.stop(); + await acl.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('sets, gets, and unsets vault permissions', async () => { + const vaultName = 'test-vault'; + await vaultManager.createVault(vaultName); + // Set permissions + const vault = new vaultsPB.Vault(); + vault.setNameOrId(vaultName); + const node = new nodesPB.Node(); + node.setNodeId(nodesUtils.encodeNodeId(nodeId)); + const permissions = new vaultsPB.Permissions(); + permissions.setVault(vault); + permissions.setNode(node); + permissions.setVaultPermissionsList(['clone', 'pull']); + const setResponse = await grpcClient.vaultsPermissionSet( + permissions, + clientUtils.encodeAuthFromPassword(password), + ); + expect(setResponse).toBeInstanceOf(utilsPB.StatusMessage); + expect(setResponse.getSuccess()).toBeTruthy(); + // Get permissions + const getResponse1 = grpcClient.vaultsPermissionGet( + vault, + clientUtils.encodeAuthFromPassword(password), + ); + const list1: Record[] = []; + for await (const permission of getResponse1) { + expect(permission).toBeInstanceOf(vaultsPB.Permissions); + const permissionsList = permission.getVaultPermissionsList(); + expect(permissionsList).toContain('pull'); + expect(permissionsList).toContain('clone'); + const node = permission.getNode(); + const receivedNodeId = node?.getNodeId(); + expect(receivedNodeId).toEqual(nodesUtils.encodeNodeId(nodeId)); + list1.push(permission.toObject()); + } + expect(list1).toHaveLength(1); + // Unset permissions + const deleteResponse = await grpcClient.vaultsPermissionUnset( + permissions, + clientUtils.encodeAuthFromPassword(password), + ); + expect(deleteResponse).toBeInstanceOf(utilsPB.StatusMessage); + expect(deleteResponse.getSuccess()).toBeTruthy(); + // Check permissions were unset + const getResponse2 = grpcClient.vaultsPermissionGet( + vault, + clientUtils.encodeAuthFromPassword(password), + ); + const list2: Record[] = []; + for await (const permission of getResponse2) { + expect(permission).toBeInstanceOf(vaultsPB.Permissions); + const permissionsList = permission.getVaultPermissionsList(); + expect(permissionsList).toEqual([]); + const node = permission.getNode(); + const receivedNodeId = node?.getNodeId(); + expect(receivedNodeId).toEqual(nodesUtils.encodeNodeId(nodeId)); + list2.push(permission.toObject()); + } + expect(list2).toHaveLength(1); + }); +}); diff --git a/tests/client/service/vaultsPull.test.ts b/tests/client/service/vaultsPull.test.ts new file mode 100644 index 000000000..8240e167d --- /dev/null +++ b/tests/client/service/vaultsPull.test.ts @@ -0,0 +1,99 @@ +import type { Host, Port } from '@/network/types'; +import type KeyManager from '@/keys/KeyManager'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsPull from '@/client/service/vaultsPull'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsPull', () => { + const logger = new Logger('vaultsPull test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager: {} as KeyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsPull: vaultsPull({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test.todo('pulls from a vault'); +}); diff --git a/tests/client/service/vaultsRename.test.ts b/tests/client/service/vaultsRename.test.ts new file mode 100644 index 000000000..0e7dd856e --- /dev/null +++ b/tests/client/service/vaultsRename.test.ts @@ -0,0 +1,128 @@ +import type { Host, Port } from '@/network/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsRename from '@/client/service/vaultsRename'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as keysUtils from '@/keys/utils'; +import * as vaultsUtils from '@/vaults/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsRename', () => { + const logger = new Logger('vaultsRename test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsRename: vaultsRename({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('should rename vault', async () => { + const vaultId1 = await vaultManager.createVault('test-vault1'); + const vaultRenameMessage = new vaultsPB.Rename(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId1)); + vaultRenameMessage.setVault(vaultMessage); + vaultRenameMessage.setNewName('test-vault2'); + const vaultId2 = await grpcClient.vaultsRename( + vaultRenameMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(vaultId2).toBeInstanceOf(vaultsPB.Vault); + expect(vaultsUtils.decodeVaultId(vaultId2.getNameOrId())).toStrictEqual( + vaultId1, + ); + const renamedVaultId = await vaultManager.getVaultId('test-vault2'); + expect(renamedVaultId).toEqual(vaultId1); + }); +}); diff --git a/tests/client/service/vaultsScan.test.ts b/tests/client/service/vaultsScan.test.ts new file mode 100644 index 000000000..40abc72eb --- /dev/null +++ b/tests/client/service/vaultsScan.test.ts @@ -0,0 +1,91 @@ +import type { DB } from '@matrixai/db'; +import type { Host, Port } from '@/network/types'; +import type KeyManager from '@/keys/KeyManager'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +import fs from 'fs'; +import path from 'path'; +import os from 'os'; +import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +import { Metadata } from '@grpc/grpc-js'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsScan from '@/client/service/vaultsScan'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsScan', () => { + const logger = new Logger('vaultsScan test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db: {} as DB, + acl: {} as ACL, + keyManager: {} as KeyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsScan: vaultsScan({ + authenticate, + vaultManager, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test.todo('scans a vault'); +}); diff --git a/tests/client/service/vaultsVersion.test.ts b/tests/client/service/vaultsVersion.test.ts new file mode 100644 index 000000000..09373743a --- /dev/null +++ b/tests/client/service/vaultsVersion.test.ts @@ -0,0 +1,182 @@ +import type { Host, Port } from '@/network/types'; +import type { VaultId } from '@/vaults/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsVersion from '@/client/service/vaultsVersion'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as keysUtils from '@/keys/utils'; +import * as vaultsUtils from '@/vaults/utils'; +import * as vaultsErrors from '@/vaults/errors'; +import * as testUtils from '../../utils'; + +describe('vaultsVersion', () => { + const logger = new Logger('vaultsVersion test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + const secretVer1 = { + name: 'secret1v1', + content: 'Secret-1-content-ver1', + }; + const secretVer2 = { + name: 'secret1v2', + content: 'Secret-1-content-ver2', + }; + const vaultName = 'test-vault'; + let vaultId: VaultId; + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + vaultId = await vaultManager.createVault(vaultName); + const clientService = { + vaultsVersion: vaultsVersion({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('should switch a vault to a version', async () => { + // Commit some history + const ver1Oid = await vaultManager.withVaults([vaultId], async (vault) => { + await vault.writeF(async (efs) => { + await efs.writeFile(secretVer1.name, secretVer1.content); + }); + const ver1Oid = (await vault.log())[0].commitId; + await vault.writeF(async (efs) => { + await efs.writeFile(secretVer2.name, secretVer2.content); + }); + return ver1Oid; + }); + // Revert the version + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultName); + const vaultVersionMessage = new vaultsPB.Version(); + vaultVersionMessage.setVault(vaultMessage); + vaultVersionMessage.setVersionId(ver1Oid); + const version = await grpcClient.vaultsVersion( + vaultVersionMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(version.getIsLatestVersion()).toBeFalsy(); + // Read old history + await vaultManager.withVaults([vaultId], async (vault) => { + await vault.readF(async (efs) => { + expect((await efs.readFile(secretVer1.name)).toString()).toStrictEqual( + secretVer1.content, + ); + }); + }); + }); + test('should fail to find a non existent version', async () => { + // Revert the version + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + const vaultVersionMessage = new vaultsPB.Version(); + vaultVersionMessage.setVault(vaultMessage); + vaultVersionMessage.setVersionId('invalidOid'); + const version = grpcClient.vaultsVersion( + vaultVersionMessage, + clientUtils.encodeAuthFromPassword(password), + ); + await testUtils.expectRemoteError( + version, + vaultsErrors.ErrorVaultReferenceInvalid, + ); + vaultVersionMessage.setVersionId( + '7660aa9a2fee90e875c2d19e5deefe882ca1d4d9', + ); + const version2 = grpcClient.vaultsVersion( + vaultVersionMessage, + clientUtils.encodeAuthFromPassword(password), + ); + await testUtils.expectRemoteError( + version2, + vaultsErrors.ErrorVaultReferenceMissing, + ); + }); +}); From 679826cb6026e3555b6409b1932c0469c6852b79 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 25 May 2022 14:39:12 +1000 Subject: [PATCH 50/74] test: fixed broken proxy tests Problem was with the tests themselves so i've fixed the tests. If there are any similar issues crop up later, then we can explore the underlying cause in depth. However, it is low priority for now. --- tests/network/Proxy.test.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/network/Proxy.test.ts b/tests/network/Proxy.test.ts index afd93c3b4..b418d6544 100644 --- a/tests/network/Proxy.test.ts +++ b/tests/network/Proxy.test.ts @@ -1,12 +1,12 @@ -import type { Socket, AddressInfo } from 'net'; +import type { AddressInfo, Socket } from 'net'; import type { KeyPairPem } from '@/keys/types'; import type { Host, Port } from '@/network/types'; -import http from 'http'; import net from 'net'; +import http from 'http'; import tls from 'tls'; import UTP from 'utp-native'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; -import { promisify, promise, timerStart, timerStop, poll } from '@/utils'; +import { poll, promise, promisify, timerStart, timerStop } from '@/utils'; import Proxy from '@/network/Proxy'; import * as networkUtils from '@/network/utils'; import * as networkErrors from '@/network/errors'; @@ -27,7 +27,7 @@ async function httpConnect( path: string, ): Promise { const tokenEncoded = Buffer.from(token, 'utf-8').toString('base64'); - const socket = await new Promise((resolve, reject) => { + return await new Promise((resolve, reject) => { const req = http.request({ method: 'CONNECT', path: path, @@ -49,7 +49,6 @@ async function httpConnect( reject(e); }); }); - return socket; } /** From 84ca544ff21e31e350098edb245ed45d3cd6dfef Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 25 May 2022 20:17:36 +1000 Subject: [PATCH 51/74] tests: fixing remaining tests --- tests/client/rpcVaults.test.ts | 10 ++++ tests/grpc/GRPCServer.test.ts | 5 ++ tests/grpc/utils.test.ts | 93 ++++++++++++++++++------------ tests/grpc/utils/GRPCClientTest.ts | 8 +++ tests/grpc/utils/testService.ts | 13 ++++- 5 files changed, 89 insertions(+), 40 deletions(-) diff --git a/tests/client/rpcVaults.test.ts b/tests/client/rpcVaults.test.ts index 0d0ccc6d7..eefd4943f 100644 --- a/tests/client/rpcVaults.test.ts +++ b/tests/client/rpcVaults.test.ts @@ -4,6 +4,7 @@ import type { VaultName } from '@/vaults/types'; import type { ClientServiceClient } from '@/proto/js/polykey/v1/client_service_grpc_pb'; import type { Stat } from 'encryptedfs'; import type * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +import type { ClientMetadata } from '@/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; @@ -111,6 +112,7 @@ describe('Vaults client service', () => { test('should make a directory in a vault', async () => { const mkdirVault = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.vaultsSecretsMkdir, ); @@ -133,6 +135,7 @@ describe('Vaults client service', () => { const listSecretsVault = grpcUtils.promisifyReadableStreamCall( client, + {} as ClientMetadata, client.vaultsSecretsList, ); @@ -158,6 +161,7 @@ describe('Vaults client service', () => { const deleteSecretVault = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.vaultsSecretsDelete, ); @@ -187,6 +191,7 @@ describe('Vaults client service', () => { const editSecretVault = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.vaultsSecretsEdit, ); const vaultId = await vaultManager.createVault(vaultList[0]); @@ -214,6 +219,7 @@ describe('Vaults client service', () => { test('should get secrets in a vault', async () => { const getSecretVault = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.vaultsSecretsGet, ); const vaultId = await vaultManager.createVault(vaultList[0]); @@ -235,6 +241,7 @@ describe('Vaults client service', () => { const renameSecretVault = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.vaultsSecretsRename, ); const vaultId = await vaultManager.createVault(vaultList[0]); @@ -265,6 +272,7 @@ describe('Vaults client service', () => { const newSecretVault = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.vaultsSecretsNew, ); @@ -288,6 +296,7 @@ describe('Vaults client service', () => { const newDirSecretVault = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.vaultsSecretsNewDir, ); @@ -315,6 +324,7 @@ describe('Vaults client service', () => { test('should stat a file', async () => { const getSecretStat = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.vaultsSecretsStat, ); const vaultId = await vaultManager.createVault(vaultList[0]); diff --git a/tests/grpc/GRPCServer.test.ts b/tests/grpc/GRPCServer.test.ts index 9b5c54809..6b77673e4 100644 --- a/tests/grpc/GRPCServer.test.ts +++ b/tests/grpc/GRPCServer.test.ts @@ -1,5 +1,6 @@ import type { Authenticate } from '@/client/types'; import type { Host, Port } from '@/network/types'; +import type { ClientMetadata } from '@/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; @@ -160,6 +161,7 @@ describe('GRPCServer', () => { ); const unary = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.unary, ); const m = new utilsPB.EchoMessage(); @@ -213,6 +215,7 @@ describe('GRPCServer', () => { ); const unary1 = grpcUtils.promisifyUnaryCall( client1, + {} as ClientMetadata, client1.unary, ); const m1 = new utilsPB.EchoMessage(); @@ -250,6 +253,7 @@ describe('GRPCServer', () => { ); const unary2 = grpcUtils.promisifyUnaryCall( client2, + {} as ClientMetadata, client2.unary, ); const m3 = new utilsPB.EchoMessage(); @@ -303,6 +307,7 @@ describe('GRPCServer', () => { ); const unary = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.unaryAuthenticated, ); const m = new utilsPB.EchoMessage(); diff --git a/tests/grpc/utils.test.ts b/tests/grpc/utils.test.ts index 496f6553b..82a8e2c21 100644 --- a/tests/grpc/utils.test.ts +++ b/tests/grpc/utils.test.ts @@ -1,4 +1,5 @@ import type { TestServiceClient } from '@/proto/js/polykey/v1/test_service_grpc_pb'; +import type { ClientMetadata } from '@/types'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import { getLogger } from '@grpc/grpc-js/build/src/logging'; @@ -41,6 +42,7 @@ describe('GRPC utils', () => { test('promisified client unary call', async () => { const unary = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.unary, ); const messageTo = new utilsPB.EchoMessage(); @@ -53,6 +55,7 @@ describe('GRPC utils', () => { test('promisified client unary call error', async () => { const unary = grpcUtils.promisifyUnaryCall( client, + {} as ClientMetadata, client.unary, ); const messageTo = new utilsPB.EchoMessage(); @@ -74,6 +77,7 @@ describe('GRPC utils', () => { const serverStream = grpcUtils.promisifyReadableStreamCall( client, + {} as ClientMetadata, client.serverStream, ); const challenge = '4444'; @@ -99,6 +103,7 @@ describe('GRPC utils', () => { const serverStream = grpcUtils.promisifyReadableStreamCall( client, + {} as ClientMetadata, client.serverStream, ); const challenge = 'error'; @@ -123,6 +128,7 @@ describe('GRPC utils', () => { const serverStream = grpcUtils.promisifyReadableStreamCall( client, + {} as ClientMetadata, client.serverStream, ); const challenge = '4444'; @@ -147,6 +153,7 @@ describe('GRPC utils', () => { const serverStream = grpcUtils.promisifyReadableStreamCall( client, + {} as ClientMetadata, client.serverStream, ); const challenge = '4444'; @@ -174,7 +181,7 @@ describe('GRPC utils', () => { const clientStream = grpcUtils.promisifyWritableStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, client.clientStream); + >(client, {} as ClientMetadata, client.clientStream); const [genStream, response] = clientStream(); const m = new utilsPB.EchoMessage(); m.setChallenge('d89f7u983e4d'); @@ -191,7 +198,7 @@ describe('GRPC utils', () => { const clientStream = grpcUtils.promisifyWritableStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, client.clientStream); + >(client, {} as ClientMetadata, client.clientStream); const [genStream, response] = clientStream(); const result1 = await genStream.next(null); // Closed stream expect(result1).toMatchObject({ @@ -212,7 +219,7 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, client.duplexStream); + >(client, {} as ClientMetadata, client.duplexStream); const genDuplex = duplexStream(); const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('d89f7u983e4d'); @@ -230,7 +237,7 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, client.duplexStream); + >(client, {} as ClientMetadata, client.duplexStream); const genDuplex = duplexStream(); await genDuplex.next(null); expect(genDuplex.stream.destroyed).toBe(true); @@ -240,7 +247,7 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, client.duplexStream); + >(client, {} as ClientMetadata, client.duplexStream); const genDuplex = duplexStream(); // When duplex streams are ended, reading will hang await genDuplex.write(null); @@ -253,7 +260,7 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, client.duplexStream); + >(client, {} as ClientMetadata, client.duplexStream); const genDuplex = duplexStream(); await genDuplex.read(null); const messageTo = new utilsPB.EchoMessage(); @@ -273,7 +280,7 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, client.duplexStream); + >(client, {} as ClientMetadata, client.duplexStream); const genDuplex = duplexStream(); const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); @@ -288,7 +295,7 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, client.duplexStream); + >(client, {} as ClientMetadata, client.duplexStream); const genDuplex = duplexStream(); const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); @@ -315,13 +322,16 @@ describe('GRPC utils', () => { type: 'ErrorPolykey', data: expect.any(Object), }); - const deserialisedError = grpcUtils.toError({ - name: '', - message: '', - code: 2, - details: '', - metadata: serialised, - }); + const deserialisedError = grpcUtils.toError( + { + name: '', + message: '', + code: 2, + details: '', + metadata: serialised, + }, + {} as ClientMetadata, + ); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykey); @@ -340,32 +350,38 @@ describe('GRPC utils', () => { type: 'TypeError', data: expect.any(Object), }); - const deserialisedError = grpcUtils.toError({ - name: '', - message: '', - code: 2, - details: '', - metadata: serialised, - }); + const deserialisedError = grpcUtils.toError( + { + name: '', + message: '', + code: 2, + details: '', + metadata: serialised, + }, + {} as ClientMetadata, + ); 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 () => { + test('serialising and de-serialising 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, - }); + const deserialisedError = grpcUtils.toError( + { + name: '', + message: '', + code: 2, + details: '', + metadata: serialised, + }, + {} as ClientMetadata, + ); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe(''); expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykeyUnknown); @@ -396,13 +412,16 @@ describe('GRPC utils', () => { data: error.data, }, }); - const deserialisedError = grpcUtils.toError({ - name: '', - message: '', - code: 2, - details: '', - metadata: serialised, - }); + const deserialisedError = grpcUtils.toError( + { + name: '', + message: '', + code: 2, + details: '', + metadata: serialised, + }, + {} as ClientMetadata, + ); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykey); diff --git a/tests/grpc/utils/GRPCClientTest.ts b/tests/grpc/utils/GRPCClientTest.ts index 9cb176377..b628eba27 100644 --- a/tests/grpc/utils/GRPCClientTest.ts +++ b/tests/grpc/utils/GRPCClientTest.ts @@ -5,6 +5,7 @@ import type { Host, Port, TLSConfig, ProxyConfig } from '@/network/types'; import type * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import type { ClientReadableStream } from '@grpc/grpc-js/build/src/call'; import type { AsyncGeneratorReadableStreamClient } from '@/grpc/types'; +import type { ClientMetadata } from '@/types'; import Logger from '@matrixai/logger'; import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy'; import GRPCClient from '@/grpc/GRPCClient'; @@ -75,6 +76,7 @@ class GRPCClientTest extends GRPCClient { public unary(...args) { return grpcUtils.promisifyUnaryCall( this.client, + {} as ClientMetadata, this.client.unary, )(...args); } @@ -83,6 +85,7 @@ class GRPCClientTest extends GRPCClient { public serverStream(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, + {} as ClientMetadata, this.client.serverStream, )(...args); } @@ -94,6 +97,7 @@ class GRPCClientTest extends GRPCClient { utilsPB.EchoMessage >( this.client, + {} as ClientMetadata, this.client.clientStream, )(...args); } @@ -105,6 +109,7 @@ class GRPCClientTest extends GRPCClient { utilsPB.EchoMessage >( this.client, + {} as ClientMetadata, this.client.duplexStream, )(...args); } @@ -113,6 +118,7 @@ class GRPCClientTest extends GRPCClient { public unaryAuthenticated(...args) { return grpcUtils.promisifyUnaryCall( this.client, + {} as ClientMetadata, this.client.unaryAuthenticated, )(...args); } @@ -126,6 +132,7 @@ class GRPCClientTest extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, + {} as ClientMetadata, this.client.serverStreamFail, )(...args); } @@ -134,6 +141,7 @@ class GRPCClientTest extends GRPCClient { public unaryFail(...args) { return grpcUtils.promisifyUnaryCall( this.client, + {} as ClientMetadata, this.client.unaryFail, )(...args); } diff --git a/tests/grpc/utils/testService.ts b/tests/grpc/utils/testService.ts index 38cd50128..2769d103e 100644 --- a/tests/grpc/utils/testService.ts +++ b/tests/grpc/utils/testService.ts @@ -7,6 +7,7 @@ import type { Authenticate } from '@/client/types'; import type { SessionToken } from '@/sessions/types'; import type { ITestServiceServer } from '@/proto/js/polykey/v1/test_service_grpc_pb'; +import type { ClientMetadata } from '@/types'; import Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '@/grpc/utils'; @@ -102,8 +103,10 @@ function createTestService({ ); call.sendMetadata(meta); } - const genReadable = - grpcUtils.generatorReadable(call); + const genReadable = grpcUtils.generatorReadable( + call, + {} as ClientMetadata, + ); let data = ''; try { for await (const m of genReadable) { @@ -132,7 +135,11 @@ function createTestService({ ); call.sendMetadata(meta); } - const genDuplex = grpcUtils.generatorDuplex(call, false); + const genDuplex = grpcUtils.generatorDuplex( + call, + {} as ClientMetadata, + false, + ); const readStatus = await genDuplex.read(); // If nothing to read, end and destroy if (readStatus.done) { From 7b8afbe4a026f7a017f40ed411b9cc82ebeea4e4 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Thu, 26 May 2022 12:05:26 +1000 Subject: [PATCH 52/74] tests: grpc tests fixes There were places where ClientMetadata was not being provided to grpc calls (`{} as ClientMetadata`) however this information is required in order to construct ErrorPolykeyRemote. Where metadata is needed in tests it is either now taken from constants used in the tests or mocked. There was also an issue with error descriptions not being serialised/deserialised which is now fixed. Also some brittle test cases for error messages were removed. --- src/ErrorPolykey.ts | 2 + tests/grpc/GRPCServer.test.ts | 29 +++- tests/grpc/utils.test.ts | 205 +++++++++++++++++++++++++---- tests/grpc/utils/GRPCClientTest.ts | 50 +++++-- tests/grpc/utils/testService.ts | 20 ++- 5 files changed, 268 insertions(+), 38 deletions(-) diff --git a/src/ErrorPolykey.ts b/src/ErrorPolykey.ts index b7286859e..b4a1d046f 100644 --- a/src/ErrorPolykey.ts +++ b/src/ErrorPolykey.ts @@ -16,6 +16,7 @@ class ErrorPolykey extends AbstractError { typeof json.data !== 'object' || typeof json.data.message !== 'string' || isNaN(Date.parse(json.data.timestamp)) || + typeof json.data.description !== 'string' || typeof json.data.data !== 'object' || typeof json.data.exitCode !== 'number' || ('stack' in json.data && typeof json.data.stack !== 'string') @@ -34,6 +35,7 @@ class ErrorPolykey extends AbstractError { public toJSON(): any { const json = super.toJSON(); + json.data.description = this.description; json.data.exitCode = this.exitCode; return json; } diff --git a/tests/grpc/GRPCServer.test.ts b/tests/grpc/GRPCServer.test.ts index 6b77673e4..83455859b 100644 --- a/tests/grpc/GRPCServer.test.ts +++ b/tests/grpc/GRPCServer.test.ts @@ -1,6 +1,5 @@ import type { Authenticate } from '@/client/types'; import type { Host, Port } from '@/network/types'; -import type { ClientMetadata } from '@/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; @@ -161,7 +160,12 @@ describe('GRPCServer', () => { ); const unary = grpcUtils.promisifyUnaryCall( client, - {} as ClientMetadata, + { + nodeId: nodeIdServer, + host: server.getHost(), + port: server.getPort(), + command: 'unary', + }, client.unary, ); const m = new utilsPB.EchoMessage(); @@ -215,7 +219,12 @@ describe('GRPCServer', () => { ); const unary1 = grpcUtils.promisifyUnaryCall( client1, - {} as ClientMetadata, + { + nodeId: nodeIdServer1, + host: server.getHost(), + port: server.getPort(), + command: 'unary1', + }, client1.unary, ); const m1 = new utilsPB.EchoMessage(); @@ -253,7 +262,12 @@ describe('GRPCServer', () => { ); const unary2 = grpcUtils.promisifyUnaryCall( client2, - {} as ClientMetadata, + { + nodeId: nodeIdServer2, + host: server.getHost(), + port: server.getPort(), + command: 'unary2', + }, client2.unary, ); const m3 = new utilsPB.EchoMessage(); @@ -307,7 +321,12 @@ describe('GRPCServer', () => { ); const unary = grpcUtils.promisifyUnaryCall( client, - {} as ClientMetadata, + { + nodeId: nodeIdServer, + host: server.getHost(), + port: server.getPort(), + command: 'unary', + }, client.unaryAuthenticated, ); const m = new utilsPB.EchoMessage(); diff --git a/tests/grpc/utils.test.ts b/tests/grpc/utils.test.ts index 82a8e2c21..7364d6bff 100644 --- a/tests/grpc/utils.test.ts +++ b/tests/grpc/utils.test.ts @@ -1,5 +1,5 @@ import type { TestServiceClient } from '@/proto/js/polykey/v1/test_service_grpc_pb'; -import type { ClientMetadata } from '@/types'; +import type { Host, Port } from '@/network/types'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import { getLogger } from '@grpc/grpc-js/build/src/logging'; @@ -8,12 +8,15 @@ 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'; +import * as testUtils from '../utils'; describe('GRPC utils', () => { const logger = new Logger('GRPC utils Test', LogLevel.WARN, [ new StreamHandler(), ]); let client: TestServiceClient, server: grpc.Server, port: number; + const nodeId = testUtils.generateRandomNodeId(); + const host = '127.0.0.1' as Host; beforeAll(async () => { // Mocked authenticate always passes authentication const authenticate = async (metaClient, metaServer = new grpc.Metadata()) => @@ -42,7 +45,12 @@ describe('GRPC utils', () => { test('promisified client unary call', async () => { const unary = grpcUtils.promisifyUnaryCall( client, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'unary', + }, client.unary, ); const messageTo = new utilsPB.EchoMessage(); @@ -55,7 +63,12 @@ describe('GRPC utils', () => { test('promisified client unary call error', async () => { const unary = grpcUtils.promisifyUnaryCall( client, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'unary', + }, client.unary, ); const messageTo = new utilsPB.EchoMessage(); @@ -67,6 +80,10 @@ describe('GRPC utils', () => { } catch (e) { // This information comes from the server expect(e.message).toBe('test error'); + expect(e.metadata.nodeId).toBe(nodeId); + expect(e.metadata.host).toBe(host); + expect(e.metadata.port).toBe(port); + expect(e.metadata.command).toBe('unary'); expect(e.cause).toBeInstanceOf(grpcErrors.ErrorGRPC); expect(e.cause.data).toMatchObject({ grpc: true, @@ -77,7 +94,12 @@ describe('GRPC utils', () => { const serverStream = grpcUtils.promisifyReadableStreamCall( client, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'serverStream', + }, client.serverStream, ); const challenge = '4444'; @@ -103,7 +125,12 @@ describe('GRPC utils', () => { const serverStream = grpcUtils.promisifyReadableStreamCall( client, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'serverStream', + }, client.serverStream, ); const challenge = 'error'; @@ -128,7 +155,12 @@ describe('GRPC utils', () => { const serverStream = grpcUtils.promisifyReadableStreamCall( client, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'serverStream', + }, client.serverStream, ); const challenge = '4444'; @@ -153,7 +185,12 @@ describe('GRPC utils', () => { const serverStream = grpcUtils.promisifyReadableStreamCall( client, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'serverStream', + }, client.serverStream, ); const challenge = '4444'; @@ -181,7 +218,16 @@ describe('GRPC utils', () => { const clientStream = grpcUtils.promisifyWritableStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, {} as ClientMetadata, client.clientStream); + >( + client, + { + nodeId, + host, + port: port as Port, + command: 'clientStream', + }, + client.clientStream, + ); const [genStream, response] = clientStream(); const m = new utilsPB.EchoMessage(); m.setChallenge('d89f7u983e4d'); @@ -198,7 +244,16 @@ describe('GRPC utils', () => { const clientStream = grpcUtils.promisifyWritableStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, {} as ClientMetadata, client.clientStream); + >( + client, + { + nodeId, + host, + port: port as Port, + command: 'clientStream', + }, + client.clientStream, + ); const [genStream, response] = clientStream(); const result1 = await genStream.next(null); // Closed stream expect(result1).toMatchObject({ @@ -219,7 +274,16 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, {} as ClientMetadata, client.duplexStream); + >( + client, + { + nodeId, + host, + port: port as Port, + command: 'duplexStream', + }, + client.duplexStream, + ); const genDuplex = duplexStream(); const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('d89f7u983e4d'); @@ -237,7 +301,16 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, {} as ClientMetadata, client.duplexStream); + >( + client, + { + nodeId, + host, + port: port as Port, + command: 'duplexStream', + }, + client.duplexStream, + ); const genDuplex = duplexStream(); await genDuplex.next(null); expect(genDuplex.stream.destroyed).toBe(true); @@ -247,7 +320,16 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, {} as ClientMetadata, client.duplexStream); + >( + client, + { + nodeId, + host, + port: port as Port, + command: 'duplexStream', + }, + client.duplexStream, + ); const genDuplex = duplexStream(); // When duplex streams are ended, reading will hang await genDuplex.write(null); @@ -260,7 +342,16 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, {} as ClientMetadata, client.duplexStream); + >( + client, + { + nodeId, + host, + port: port as Port, + command: 'duplexStream', + }, + client.duplexStream, + ); const genDuplex = duplexStream(); await genDuplex.read(null); const messageTo = new utilsPB.EchoMessage(); @@ -280,7 +371,16 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, {} as ClientMetadata, client.duplexStream); + >( + client, + { + nodeId, + host, + port: port as Port, + command: 'duplexStream', + }, + client.duplexStream, + ); const genDuplex = duplexStream(); const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); @@ -295,7 +395,16 @@ describe('GRPC utils', () => { const duplexStream = grpcUtils.promisifyDuplexStreamCall< utilsPB.EchoMessage, utilsPB.EchoMessage - >(client, {} as ClientMetadata, client.duplexStream); + >( + client, + { + nodeId, + host, + port: port as Port, + command: 'duplexStream', + }, + client.duplexStream, + ); const genDuplex = duplexStream(); const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); @@ -330,10 +439,23 @@ describe('GRPC utils', () => { details: '', metadata: serialised, }, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'testCall', + }, ); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); + // @ts-ignore - already checked above that error is ErrorPolykeyRemote + expect(deserialisedError.metadata.nodeId).toBe(nodeId); + // @ts-ignore + expect(deserialisedError.metadata.host).toBe(host); + // @ts-ignore + expect(deserialisedError.metadata.port).toBe(port); + // @ts-ignore + expect(deserialisedError.metadata.command).toBe('testCall'); expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykey); expect(deserialisedError.cause.message).toBe('test error'); expect(deserialisedError.cause.exitCode).toBe(255); @@ -358,10 +480,23 @@ describe('GRPC utils', () => { details: '', metadata: serialised, }, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'testCall', + }, ); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); + // @ts-ignore - already checked above that error is ErrorPolykeyRemote + expect(deserialisedError.metadata.nodeId).toBe(nodeId); + // @ts-ignore + expect(deserialisedError.metadata.host).toBe(host); + // @ts-ignore + expect(deserialisedError.metadata.port).toBe(port); + // @ts-ignore + expect(deserialisedError.metadata.command).toBe('testCall'); expect(deserialisedError.cause).toBeInstanceOf(TypeError); expect(deserialisedError.cause.message).toBe('test error'); expect(deserialisedError.cause.stack).toBe(error.stack); @@ -380,13 +515,26 @@ describe('GRPC utils', () => { details: '', metadata: serialised, }, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'testCall', + }, ); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); - expect(deserialisedError.message).toBe(''); + // @ts-ignore - already checked above that error is ErrorPolykeyRemote + expect(deserialisedError.metadata.nodeId).toBe(nodeId); + // @ts-ignore + expect(deserialisedError.metadata.host).toBe(host); + // @ts-ignore + expect(deserialisedError.metadata.port).toBe(port); + // @ts-ignore + expect(deserialisedError.metadata.command).toBe('testCall'); expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykeyUnknown); - expect(deserialisedError.cause.message).toBe(''); - expect(deserialisedError.cause.data).toEqual('not an error'); + // This is slightly brittle because it's based on what we choose to do + // with unknown data in our grpc reviver + expect(deserialisedError.cause.data.json).toEqual('not an error'); }); test('serialising and deserialising sensitive errors', async () => { const timestamp = new Date(); @@ -420,10 +568,23 @@ describe('GRPC utils', () => { details: '', metadata: serialised, }, - {} as ClientMetadata, + { + nodeId, + host, + port: port as Port, + command: 'testCall', + }, ); expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); + // @ts-ignore - already checked above that error is ErrorPolykeyRemote + expect(deserialisedError.metadata.nodeId).toBe(nodeId); + // @ts-ignore + expect(deserialisedError.metadata.host).toBe(host); + // @ts-ignore + expect(deserialisedError.metadata.port).toBe(port); + // @ts-ignore + expect(deserialisedError.metadata.command).toBe('testCall'); expect(deserialisedError.cause).toBeInstanceOf(errors.ErrorPolykey); expect(deserialisedError.cause.message).toBe('test error'); expect(deserialisedError.cause.exitCode).toBe(255); diff --git a/tests/grpc/utils/GRPCClientTest.ts b/tests/grpc/utils/GRPCClientTest.ts index b628eba27..e3c5f9489 100644 --- a/tests/grpc/utils/GRPCClientTest.ts +++ b/tests/grpc/utils/GRPCClientTest.ts @@ -5,7 +5,6 @@ import type { Host, Port, TLSConfig, ProxyConfig } from '@/network/types'; import type * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import type { ClientReadableStream } from '@grpc/grpc-js/build/src/call'; import type { AsyncGeneratorReadableStreamClient } from '@/grpc/types'; -import type { ClientMetadata } from '@/types'; import Logger from '@matrixai/logger'; import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy'; import GRPCClient from '@/grpc/GRPCClient'; @@ -76,7 +75,12 @@ class GRPCClientTest extends GRPCClient { public unary(...args) { return grpcUtils.promisifyUnaryCall( this.client, - {} as ClientMetadata, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + command: this.unary.name, + }, this.client.unary, )(...args); } @@ -85,7 +89,12 @@ class GRPCClientTest extends GRPCClient { public serverStream(...args) { return grpcUtils.promisifyReadableStreamCall( this.client, - {} as ClientMetadata, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + command: this.serverStream.name, + }, this.client.serverStream, )(...args); } @@ -97,7 +106,12 @@ class GRPCClientTest extends GRPCClient { utilsPB.EchoMessage >( this.client, - {} as ClientMetadata, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + command: this.clientStream.name, + }, this.client.clientStream, )(...args); } @@ -109,7 +123,12 @@ class GRPCClientTest extends GRPCClient { utilsPB.EchoMessage >( this.client, - {} as ClientMetadata, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + command: this.duplexStream.name, + }, this.client.duplexStream, )(...args); } @@ -118,7 +137,12 @@ class GRPCClientTest extends GRPCClient { public unaryAuthenticated(...args) { return grpcUtils.promisifyUnaryCall( this.client, - {} as ClientMetadata, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + command: this.unaryAuthenticated.name, + }, this.client.unaryAuthenticated, )(...args); } @@ -132,7 +156,12 @@ class GRPCClientTest extends GRPCClient { > { return grpcUtils.promisifyReadableStreamCall( this.client, - {} as ClientMetadata, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + command: this.serverStreamFail.name, + }, this.client.serverStreamFail, )(...args); } @@ -141,7 +170,12 @@ class GRPCClientTest extends GRPCClient { public unaryFail(...args) { return grpcUtils.promisifyUnaryCall( this.client, - {} as ClientMetadata, + { + nodeId: this.nodeId, + host: this.host, + port: this.port, + command: this.unaryFail.name, + }, this.client.unaryFail, )(...args); } diff --git a/tests/grpc/utils/testService.ts b/tests/grpc/utils/testService.ts index 2769d103e..bec280ffc 100644 --- a/tests/grpc/utils/testService.ts +++ b/tests/grpc/utils/testService.ts @@ -7,7 +7,7 @@ import type { Authenticate } from '@/client/types'; import type { SessionToken } from '@/sessions/types'; import type { ITestServiceServer } from '@/proto/js/polykey/v1/test_service_grpc_pb'; -import type { ClientMetadata } from '@/types'; +import type { Host, Port } from '@/network/types'; import Logger from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '@/grpc/utils'; @@ -15,6 +15,7 @@ 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'; +import * as testUtils from '../../utils'; function createTestService({ authenticate, @@ -23,6 +24,9 @@ function createTestService({ authenticate: Authenticate; logger?: Logger; }) { + const nodeId = testUtils.generateRandomNodeId(); + const host = '127.0.0.1' as Host; + const port = 0 as Port; const testService: ITestServiceServer = { unary: async ( call: grpc.ServerUnaryCall, @@ -105,7 +109,12 @@ function createTestService({ } const genReadable = grpcUtils.generatorReadable( call, - {} as ClientMetadata, + { + nodeId, + host, + port, + command: 'genReadable', + }, ); let data = ''; try { @@ -137,7 +146,12 @@ function createTestService({ } const genDuplex = grpcUtils.generatorDuplex( call, - {} as ClientMetadata, + { + nodeId, + host, + port, + command: 'genDuplex', + }, false, ); const readStatus = await genDuplex.read(); From 3ca291003a821b79a49c4c2c2249c460f7228732 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Thu, 26 May 2022 14:19:31 +1000 Subject: [PATCH 53/74] tests: split vaults secrets client service tests --- src/client/GRPCClientClient.ts | 2 +- src/client/service/vaultsSecretsMkdir.ts | 2 +- tests/client/rpcVaults.test.ts | 349 ------------------ tests/client/service/vaultsLog.test.ts | 2 +- .../client/service/vaultsSecretsEdit.test.ts | 141 +++++++ .../client/service/vaultsSecretsMkdir.test.ts | 133 +++++++ .../service/vaultsSecretsNewDeleteGet.test.ts | 169 +++++++++ .../service/vaultsSecretsNewDirList.test.ts | 157 ++++++++ .../service/vaultsSecretsRename.test.ts | 143 +++++++ .../client/service/vaultsSecretsStat.test.ts | 137 +++++++ 10 files changed, 883 insertions(+), 352 deletions(-) delete mode 100644 tests/client/rpcVaults.test.ts create mode 100644 tests/client/service/vaultsSecretsEdit.test.ts create mode 100644 tests/client/service/vaultsSecretsMkdir.test.ts create mode 100644 tests/client/service/vaultsSecretsNewDeleteGet.test.ts create mode 100644 tests/client/service/vaultsSecretsNewDirList.test.ts create mode 100644 tests/client/service/vaultsSecretsRename.test.ts create mode 100644 tests/client/service/vaultsSecretsStat.test.ts diff --git a/src/client/GRPCClientClient.ts b/src/client/GRPCClientClient.ts index 9492841ed..c69d58d89 100644 --- a/src/client/GRPCClientClient.ts +++ b/src/client/GRPCClientClient.ts @@ -314,7 +314,7 @@ class GRPCClientClient extends GRPCClient { @ready(new clientErrors.ErrorClientClientDestroyed()) public vaultsSecretsMkdir(...args) { - return grpcUtils.promisifyUnaryCall( + return grpcUtils.promisifyUnaryCall( this.client, { nodeId: this.nodeId, diff --git a/src/client/service/vaultsSecretsMkdir.ts b/src/client/service/vaultsSecretsMkdir.ts index 6d5649fb5..f441207cc 100644 --- a/src/client/service/vaultsSecretsMkdir.ts +++ b/src/client/service/vaultsSecretsMkdir.ts @@ -22,7 +22,7 @@ function vaultsSecretsMkdir({ logger: Logger; }) { return async ( - call: grpc.ServerUnaryCall, + call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise => { try { diff --git a/tests/client/rpcVaults.test.ts b/tests/client/rpcVaults.test.ts deleted file mode 100644 index eefd4943f..000000000 --- a/tests/client/rpcVaults.test.ts +++ /dev/null @@ -1,349 +0,0 @@ -import type * as grpc from '@grpc/grpc-js'; -import type VaultManager from '@/vaults/VaultManager'; -import type { VaultName } from '@/vaults/types'; -import type { ClientServiceClient } from '@/proto/js/polykey/v1/client_service_grpc_pb'; -import type { Stat } from 'encryptedfs'; -import type * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; -import type { ClientMetadata } from '@/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 KeyManager from '@/keys/KeyManager'; -import Proxy from '@/network/Proxy'; -import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; -import * as secretsPB from '@/proto/js/polykey/v1/secrets/secrets_pb'; -import * as grpcUtils from '@/grpc/utils'; -import * as vaultsUtils from '@/vaults/utils'; -import * as vaultOps from '@/vaults/VaultOps'; -import * as clientUtils from './utils'; - -jest.mock('@/keys/utils', () => ({ - ...jest.requireActual('@/keys/utils'), - generateDeterministicKeyPair: - jest.requireActual('@/keys/utils').generateKeyPair, -})); - -describe('Vaults client service', () => { - const password = 'password'; - const logger = new Logger('VaultsClientServerTest', LogLevel.WARN, [ - new StreamHandler(), - ]); - const vaultList = [ - 'Vault1' as VaultName, - 'Vault2' as VaultName, - 'Vault3' as VaultName, - 'Vault4' as VaultName, - ]; - const secretList = ['Secret1', 'Secret2', 'Secret3', 'Secret4']; - - let client: ClientServiceClient; - let server: grpc.Server; - let port: number; - let dataDir: string; - let pkAgent: PolykeyAgent; - let keyManager: KeyManager; - let vaultManager: VaultManager; - let passwordFile: string; - let callCredentials: grpc.Metadata; - - beforeAll(async () => { - dataDir = await fs.promises.mkdtemp( - path.join(os.tmpdir(), 'polykey-test-'), - ); - - passwordFile = path.join(dataDir, 'password'); - await fs.promises.writeFile(passwordFile, 'password'); - const keysPath = path.join(dataDir, 'keys'); - - keyManager = await KeyManager.createKeyManager({ - keysPath, - password, - logger, - }); - - const proxy = new Proxy({ - authToken: 'abc', - logger: logger, - }); - - pkAgent = await PolykeyAgent.createPolykeyAgent({ - password, - nodePath: dataDir, - logger, - proxy, - keyManager, - }); - - vaultManager = pkAgent.vaultManager; - - [server, port] = await clientUtils.openTestClientServer({ - pkAgent, - secure: false, - }); - - client = await clientUtils.openSimpleClientClient(port); - }, global.polykeyStartupTimeout); - afterAll(async () => { - await clientUtils.closeTestClientServer(server); - clientUtils.closeSimpleClientClient(client); - - await pkAgent.stop(); - await pkAgent.destroy(); - - await fs.promises.rm(dataDir, { - force: true, - recursive: true, - }); - await fs.promises.rm(passwordFile); - }); - beforeEach(async () => { - const sessionToken = await pkAgent.sessionManager.createToken(); - callCredentials = clientUtils.createCallCredentials(sessionToken); - }); - afterEach(async () => { - const aliveVaults = await vaultManager.listVaults(); - for (const vaultId of aliveVaults.values()) { - await vaultManager.destroyVault(vaultId); - } - }); - describe('Secrets', () => { - test('should make a directory in a vault', async () => { - const mkdirVault = grpcUtils.promisifyUnaryCall( - client, - {} as ClientMetadata, - client.vaultsSecretsMkdir, - ); - - const vaultId = await vaultManager.createVault(vaultList[0]); - const dirPath = 'dir/dir1/dir2'; - const vaultMkdirMessage = new vaultsPB.Mkdir(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - vaultMkdirMessage.setVault(vaultMessage); - vaultMkdirMessage.setDirName(dirPath); - vaultMkdirMessage.setRecursive(true); - await mkdirVault(vaultMkdirMessage, callCredentials); - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.readF(async (efs) => { - expect(await efs.exists(dirPath)).toBeTruthy(); - }); - }); - }); - test('should list secrets in a vault', async () => { - const listSecretsVault = - grpcUtils.promisifyReadableStreamCall( - client, - {} as ClientMetadata, - client.vaultsSecretsList, - ); - - const vaultId = await vaultManager.createVault(vaultList[0]); - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.writeF(async (efs) => { - for (const secretName of secretList) { - await efs.writeFile(secretName, secretName); - } - }); - }); - - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - const secretsStream = listSecretsVault(vaultMessage, callCredentials); - const names: Array = []; - for await (const secret of secretsStream) { - names.push(secret.getSecretName()); - } - expect(names.sort()).toStrictEqual(secretList.sort()); - }); - test('should delete secrets in a vault', async () => { - const deleteSecretVault = - grpcUtils.promisifyUnaryCall( - client, - {} as ClientMetadata, - client.vaultsSecretsDelete, - ); - - const vaultId = await vaultManager.createVault(vaultList[0]); - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.writeF(async (efs) => { - for (const secretName of secretList) { - await efs.writeFile(secretName, secretName); - } - }); - }); - - const secretMessage = new secretsPB.Secret(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - secretMessage.setVault(vaultMessage); - secretMessage.setSecretName(secretList[0]); - await deleteSecretVault(secretMessage, callCredentials); - await vaultManager.withVaults([vaultId], async (vault) => { - const secrets = await vault.readF(async (efs) => { - return await efs.readdir('.', { encoding: 'utf8' }); - }); - expect(secrets.sort()).toEqual(secretList.slice(1).sort()); - }); - }); - test('should edit secrets in a vault', async () => { - const editSecretVault = - grpcUtils.promisifyUnaryCall( - client, - {} as ClientMetadata, - client.vaultsSecretsEdit, - ); - const vaultId = await vaultManager.createVault(vaultList[0]); - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile(secretList[0], secretList[0]); - }); - }); - const secretMessage = new secretsPB.Secret(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - secretMessage.setVault(vaultMessage); - secretMessage.setSecretName(secretList[0]); - secretMessage.setSecretContent(Buffer.from('content-change')); - await editSecretVault(secretMessage, callCredentials); - - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.readF(async (efs) => { - expect((await efs.readFile(secretList[0])).toString()).toStrictEqual( - 'content-change', - ); - }); - }); - }); - test('should get secrets in a vault', async () => { - const getSecretVault = grpcUtils.promisifyUnaryCall( - client, - {} as ClientMetadata, - client.vaultsSecretsGet, - ); - const vaultId = await vaultManager.createVault(vaultList[0]); - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile(secretList[0], secretList[0]); - }); - }); - const secretMessage = new secretsPB.Secret(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - secretMessage.setVault(vaultMessage); - secretMessage.setSecretName(secretList[0]); - const secret = await getSecretVault(secretMessage, callCredentials); - const secretContent = Buffer.from(secret.getSecretContent()).toString(); - expect(secretContent).toStrictEqual(secretList[0]); - }); - test('should rename secrets in a vault', async () => { - const renameSecretVault = - grpcUtils.promisifyUnaryCall( - client, - {} as ClientMetadata, - client.vaultsSecretsRename, - ); - const vaultId = await vaultManager.createVault(vaultList[0]); - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile(secretList[0], secretList[0]); - }); - }); - const secretRenameMessage = new secretsPB.Rename(); - const vaultMessage = new vaultsPB.Vault(); - const secretMessage = new secretsPB.Secret(); - - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - secretMessage.setSecretName(secretList[0]); - secretMessage.setVault(vaultMessage); - secretRenameMessage.setNewName(secretList[1]); - secretRenameMessage.setOldSecret(secretMessage); - await renameSecretVault(secretRenameMessage, callCredentials); - - await vaultManager.withVaults([vaultId], async (vault) => { - const secrets = await vault.readF(async (efs) => { - return await efs.readdir('.'); - }); - expect(secrets.sort()).toEqual(secretList.splice(1, 1).sort()); - }); - }); - test('should add secrets in a vault', async () => { - const newSecretVault = - grpcUtils.promisifyUnaryCall( - client, - {} as ClientMetadata, - client.vaultsSecretsNew, - ); - - const vaultId = await vaultManager.createVault(vaultList[0]); - const secretMessage = new secretsPB.Secret(); - const vaultMessage = new vaultsPB.Vault(); - - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - secretMessage.setVault(vaultMessage); - secretMessage.setSecretName(secretList[0]); - secretMessage.setSecretContent(Buffer.from(secretList[0])); - await newSecretVault(secretMessage, callCredentials); - await vaultManager.withVaults([vaultId], async (vault) => { - const secret = await vault.readF(async (efs) => { - return await efs.readFile(secretList[0], { encoding: 'utf8' }); - }); - expect(secret).toBe(secretList[0]); - }); - }); - test('should add a directory of secrets in a vault', async () => { - const newDirSecretVault = - grpcUtils.promisifyUnaryCall( - client, - {} as ClientMetadata, - client.vaultsSecretsNewDir, - ); - - const secretDir = path.join(dataDir, 'secretDir'); - await fs.promises.mkdir(secretDir); - for (const secret of secretList) { - const secretFile = path.join(secretDir, secret); - // Write secret to file - await fs.promises.writeFile(secretFile, secret); - } - const vaultId = await vaultManager.createVault(vaultList[0]); - const secretDirectoryMessage = new secretsPB.Directory(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - secretDirectoryMessage.setVault(vaultMessage); - secretDirectoryMessage.setSecretDirectory(secretDir); - await newDirSecretVault(secretDirectoryMessage, callCredentials); - await vaultManager.withVaults([vaultId], async (vault) => { - const secrets = await vaultOps.listSecrets(vault); - expect(secrets.sort()).toEqual( - secretList.map((secret) => path.join('secretDir', secret)).sort(), - ); - }); - }); - test('should stat a file', async () => { - const getSecretStat = grpcUtils.promisifyUnaryCall( - client, - {} as ClientMetadata, - client.vaultsSecretsStat, - ); - const vaultId = await vaultManager.createVault(vaultList[0]); - await vaultManager.withVaults([vaultId], async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile(secretList[0], secretList[0]); - }); - }); - const secretMessage = new secretsPB.Secret(); - const vaultMessage = new vaultsPB.Vault(); - vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); - secretMessage.setVault(vaultMessage); - secretMessage.setSecretName(secretList[0]); - const result = await getSecretStat(secretMessage, callCredentials); - const stat: Stat = JSON.parse(result.getJson()); - expect(stat.size).toBe(7); - expect(stat.blksize).toBe(4096); - expect(stat.blocks).toBe(1); - expect(stat.nlink).toBe(1); - }); - }); -}); diff --git a/tests/client/service/vaultsLog.test.ts b/tests/client/service/vaultsLog.test.ts index d2f5ed26d..9a3e9f6c9 100644 --- a/tests/client/service/vaultsLog.test.ts +++ b/tests/client/service/vaultsLog.test.ts @@ -117,7 +117,7 @@ describe('vaultsLog', () => { port: grpcServer.getPort(), logger, }); - }); + }, global.defaultTimeout * 2); afterEach(async () => { await grpcClient.destroy(); await grpcServer.stop(); diff --git a/tests/client/service/vaultsSecretsEdit.test.ts b/tests/client/service/vaultsSecretsEdit.test.ts new file mode 100644 index 000000000..0956bac33 --- /dev/null +++ b/tests/client/service/vaultsSecretsEdit.test.ts @@ -0,0 +1,141 @@ +import type { Host, Port } from '@/network/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsSecretsEdit from '@/client/service/vaultsSecretsEdit'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +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 * as clientUtils from '@/client/utils/utils'; +import * as vaultsUtils from '@/vaults/utils'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsSecretsEdit', () => { + const logger = new Logger('vaultsSecretsEdit test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsSecretsEdit: vaultsSecretsEdit({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('edits secrets', async () => { + const vaultName = 'test-vault'; + const secretName = 'test-secret'; + const vaultId = await vaultManager.createVault(vaultName); + await vaultManager.withVaults([vaultId], async (vault) => { + await vault.writeF(async (efs) => { + await efs.writeFile(secretName, secretName); + }); + }); + const secretMessage = new secretsPB.Secret(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + secretMessage.setVault(vaultMessage); + secretMessage.setSecretName(secretName); + secretMessage.setSecretContent(Buffer.from('content-change')); + const response = await grpcClient.vaultsSecretsEdit( + secretMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(response).toBeInstanceOf(utilsPB.StatusMessage); + expect(response.getSuccess()).toBeTruthy(); + await vaultManager.withVaults([vaultId], async (vault) => { + await vault.readF(async (efs) => { + expect((await efs.readFile(secretName)).toString()).toStrictEqual( + 'content-change', + ); + }); + }); + }); +}); diff --git a/tests/client/service/vaultsSecretsMkdir.test.ts b/tests/client/service/vaultsSecretsMkdir.test.ts new file mode 100644 index 000000000..1e4c1b971 --- /dev/null +++ b/tests/client/service/vaultsSecretsMkdir.test.ts @@ -0,0 +1,133 @@ +import type { Host, Port } from '@/network/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsSecretsMkdir from '@/client/service/vaultsSecretsMkdir'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as vaultsUtils from '@/vaults/utils'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsSecretsMkdir', () => { + const logger = new Logger('vaultsSecretsMkdir test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsSecretsMkdir: vaultsSecretsMkdir({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('makes a directory', async () => { + const vaultName = 'test-vault'; + const vaultId = await vaultManager.createVault(vaultName); + const dirPath = 'dir/dir1/dir2'; + const vaultMkdirMessage = new vaultsPB.Mkdir(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + vaultMkdirMessage.setVault(vaultMessage); + vaultMkdirMessage.setDirName(dirPath); + vaultMkdirMessage.setRecursive(true); + const response = await grpcClient.vaultsSecretsMkdir( + vaultMkdirMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(response).toBeInstanceOf(utilsPB.StatusMessage); + expect(response.getSuccess()).toBeTruthy(); + await vaultManager.withVaults([vaultId], async (vault) => { + await vault.readF(async (efs) => { + expect(await efs.exists(dirPath)).toBeTruthy(); + }); + }); + }); +}); diff --git a/tests/client/service/vaultsSecretsNewDeleteGet.test.ts b/tests/client/service/vaultsSecretsNewDeleteGet.test.ts new file mode 100644 index 000000000..f743f6ff0 --- /dev/null +++ b/tests/client/service/vaultsSecretsNewDeleteGet.test.ts @@ -0,0 +1,169 @@ +import type { Host, Port } from '@/network/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsSecretsNew from '@/client/service/vaultsSecretsNew'; +import vaultsSecretsDelete from '@/client/service/vaultsSecretsDelete'; +import vaultsSecretsGet from '@/client/service/vaultsSecretsGet'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +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 * as clientUtils from '@/client/utils/utils'; +import * as vaultsUtils from '@/vaults/utils'; +import * as keysUtils from '@/keys/utils'; +import * as vaultsErrors from '@/vaults/errors'; +import * as testUtils from '../../utils'; + +describe('vaultsSecretsNewDeleteGet', () => { + const logger = new Logger('vaultsSecretsNewDeleteGet test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsSecretsNew: vaultsSecretsNew({ + authenticate, + vaultManager, + db, + logger, + }), + vaultsSecretsDelete: vaultsSecretsDelete({ + authenticate, + vaultManager, + db, + logger, + }), + vaultsSecretsGet: vaultsSecretsGet({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('creates, gets, and deletes secrets', async () => { + // Create secret + const secret = 'test-secret'; + const vaultId = await vaultManager.createVault('test-vault'); + const secretMessage = new secretsPB.Secret(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + secretMessage.setVault(vaultMessage); + secretMessage.setSecretName(secret); + secretMessage.setSecretContent(Buffer.from(secret)); + const createResponse = await grpcClient.vaultsSecretsNew( + secretMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(createResponse).toBeInstanceOf(utilsPB.StatusMessage); + expect(createResponse.getSuccess()).toBeTruthy(); + // Get secret + const getResponse1 = await grpcClient.vaultsSecretsGet( + secretMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(getResponse1).toBeInstanceOf(secretsPB.Secret); + const secretContent = Buffer.from( + getResponse1.getSecretContent(), + ).toString(); + expect(secretContent).toStrictEqual(secret); + // Delete secret + const deleteResponse = await grpcClient.vaultsSecretsDelete( + secretMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(deleteResponse).toBeInstanceOf(utilsPB.StatusMessage); + expect(deleteResponse.getSuccess()).toBeTruthy(); + // Check secret was deleted + await testUtils.expectRemoteError( + grpcClient.vaultsSecretsGet( + secretMessage, + clientUtils.encodeAuthFromPassword(password), + ), + vaultsErrors.ErrorSecretsSecretUndefined, + ); + }); +}); diff --git a/tests/client/service/vaultsSecretsNewDirList.test.ts b/tests/client/service/vaultsSecretsNewDirList.test.ts new file mode 100644 index 000000000..7e8911dbd --- /dev/null +++ b/tests/client/service/vaultsSecretsNewDirList.test.ts @@ -0,0 +1,157 @@ +import type { Host, Port } from '@/network/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsSecretsNewDir from '@/client/service/vaultsSecretsNewDir'; +import vaultsSecretsList from '@/client/service/vaultsSecretsList'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +import * as secretsPB from '@/proto/js/polykey/v1/secrets/secrets_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as vaultsUtils from '@/vaults/utils'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsSecretsNewDirList', () => { + const logger = new Logger('vaultsSecretsNewDirList test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsSecretsNewDir: vaultsSecretsNewDir({ + authenticate, + vaultManager, + fs, + db, + logger, + }), + vaultsSecretsList: vaultsSecretsList({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('adds and lists a directory of secrets', async () => { + // Add directory of secrets + const vaultName = 'test-vault'; + const secretList = ['test-secret1', 'test-secret2', 'test-secret3']; + const secretDir = path.join(dataDir, 'secretDir'); + await fs.promises.mkdir(secretDir); + for (const secret of secretList) { + const secretFile = path.join(secretDir, secret); + // Write secret to file + await fs.promises.writeFile(secretFile, secret); + } + const vaultId = await vaultManager.createVault(vaultName); + const secretDirectoryMessage = new secretsPB.Directory(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + secretDirectoryMessage.setVault(vaultMessage); + secretDirectoryMessage.setSecretDirectory(secretDir); + const addResponse = await grpcClient.vaultsSecretsNewDir( + secretDirectoryMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(addResponse).toBeInstanceOf(utilsPB.StatusMessage); + expect(addResponse.getSuccess()).toBeTruthy(); + // List secrets + const listResponse = grpcClient.vaultsSecretsList( + vaultMessage, + clientUtils.encodeAuthFromPassword(password), + ); + const secrets: Array = []; + for await (const secret of listResponse) { + expect(secret).toBeInstanceOf(secretsPB.Secret); + secrets.push(secret.getSecretName()); + } + expect(secrets.sort()).toStrictEqual( + secretList.map((secret) => path.join('secretDir', secret)).sort(), + ); + }); +}); diff --git a/tests/client/service/vaultsSecretsRename.test.ts b/tests/client/service/vaultsSecretsRename.test.ts new file mode 100644 index 000000000..1d6027aa3 --- /dev/null +++ b/tests/client/service/vaultsSecretsRename.test.ts @@ -0,0 +1,143 @@ +import type { Host, Port } from '@/network/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsSecretsRename from '@/client/service/vaultsSecretsRename'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as secretsPB from '@/proto/js/polykey/v1/secrets/secrets_pb'; +import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as vaultsUtils from '@/vaults/utils'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsSecretsRename', () => { + const logger = new Logger('vaultsSecretsRename test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsSecretsRename: vaultsSecretsRename({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('renames a secret', async () => { + const vaultName = 'test-vault'; + const secretName = 'test-secret'; + const vaultId = await vaultManager.createVault(vaultName); + await vaultManager.withVaults([vaultId], async (vault) => { + await vault.writeF(async (efs) => { + await efs.writeFile(secretName, secretName); + }); + }); + const secretRenameMessage = new secretsPB.Rename(); + const vaultMessage = new vaultsPB.Vault(); + const secretMessage = new secretsPB.Secret(); + vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + secretMessage.setSecretName(secretName); + secretMessage.setVault(vaultMessage); + secretRenameMessage.setNewName('name-change'); + secretRenameMessage.setOldSecret(secretMessage); + const response = await grpcClient.vaultsSecretsRename( + secretRenameMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(response).toBeInstanceOf(utilsPB.StatusMessage); + expect(response.getSuccess()).toBeTruthy(); + await vaultManager.withVaults([vaultId], async (vault) => { + await vault.readF(async (efs) => { + expect((await efs.readFile('name-change')).toString()).toStrictEqual( + secretName, + ); + }); + }); + }); +}); diff --git a/tests/client/service/vaultsSecretsStat.test.ts b/tests/client/service/vaultsSecretsStat.test.ts new file mode 100644 index 000000000..909ee82b8 --- /dev/null +++ b/tests/client/service/vaultsSecretsStat.test.ts @@ -0,0 +1,137 @@ +import type { Stat } from 'encryptedfs'; +import type { Host, Port } from '@/network/types'; +import type NodeConnectionManager from '@/nodes/NodeConnectionManager'; +import type ACL from '@/acl/ACL'; +import type GestaltGraph from '@/gestalts/GestaltGraph'; +import type NotificationsManager from '@/notifications/NotificationsManager'; +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 { Metadata } from '@grpc/grpc-js'; +import KeyManager from '@/keys/KeyManager'; +import VaultManager from '@/vaults/VaultManager'; +import GRPCServer from '@/grpc/GRPCServer'; +import GRPCClientClient from '@/client/GRPCClientClient'; +import vaultsSecretsStat from '@/client/service/vaultsSecretsStat'; +import { ClientServiceService } from '@/proto/js/polykey/v1/client_service_grpc_pb'; +import * as vaultsPB from '@/proto/js/polykey/v1/vaults/vaults_pb'; +import * as secretsPB from '@/proto/js/polykey/v1/secrets/secrets_pb'; +import * as clientUtils from '@/client/utils/utils'; +import * as vaultsUtils from '@/vaults/utils'; +import * as keysUtils from '@/keys/utils'; +import * as testUtils from '../../utils'; + +describe('vaultsSecretsStat', () => { + const logger = new Logger('vaultsSecretsStat test', LogLevel.WARN, [ + new StreamHandler(), + ]); + const password = 'helloworld'; + const authenticate = async (metaClient, metaServer = new Metadata()) => + metaServer; + let mockedGenerateKeyPair: jest.SpyInstance; + let mockedGenerateDeterministicKeyPair: jest.SpyInstance; + beforeAll(async () => { + const globalKeyPair = await testUtils.setupGlobalKeypair(); + mockedGenerateKeyPair = jest + .spyOn(keysUtils, 'generateKeyPair') + .mockResolvedValue(globalKeyPair); + mockedGenerateDeterministicKeyPair = jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockResolvedValue(globalKeyPair); + }); + afterAll(async () => { + mockedGenerateKeyPair.mockRestore(); + mockedGenerateDeterministicKeyPair.mockRestore(); + }); + let dataDir: string; + let keyManager: KeyManager; + let db: DB; + let vaultManager: VaultManager; + let grpcServer: GRPCServer; + let grpcClient: GRPCClientClient; + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + const keysPath = path.join(dataDir, 'keys'); + keyManager = await KeyManager.createKeyManager({ + password, + keysPath, + logger, + }); + const dbPath = path.join(dataDir, 'db'); + db = await DB.createDB({ + dbPath, + logger, + }); + const vaultsPath = path.join(dataDir, 'vaults'); + vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + db, + acl: {} as ACL, + keyManager, + nodeConnectionManager: {} as NodeConnectionManager, + gestaltGraph: {} as GestaltGraph, + notificationsManager: {} as NotificationsManager, + logger, + }); + const clientService = { + vaultsSecretsStat: vaultsSecretsStat({ + authenticate, + vaultManager, + db, + logger, + }), + }; + grpcServer = new GRPCServer({ logger }); + await grpcServer.start({ + services: [[ClientServiceService, clientService]], + host: '127.0.0.1' as Host, + port: 0 as Port, + }); + grpcClient = await GRPCClientClient.createGRPCClientClient({ + nodeId: testUtils.generateRandomNodeId(), + host: '127.0.0.1' as Host, + port: grpcServer.getPort(), + logger, + }); + }); + afterEach(async () => { + await grpcClient.destroy(); + await grpcServer.stop(); + await vaultManager.stop(); + await db.stop(); + await keyManager.stop(); + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('stats a file', async () => { + const vaultName = 'test-vault'; + const secretName = 'test-secret'; + const vaultId = await vaultManager.createVault(vaultName); + await vaultManager.withVaults([vaultId], async (vault) => { + await vault.writeF(async (efs) => { + await efs.writeFile(secretName, secretName); + }); + }); + const secretMessage = new secretsPB.Secret(); + const vaultMessage = new vaultsPB.Vault(); + vaultMessage.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); + secretMessage.setVault(vaultMessage); + secretMessage.setSecretName(secretName); + const response = await grpcClient.vaultsSecretsStat( + secretMessage, + clientUtils.encodeAuthFromPassword(password), + ); + expect(response).toBeInstanceOf(secretsPB.Stat); + const stat: Stat = JSON.parse(response.getJson()); + expect(stat.size).toBe(secretName.length); + expect(stat.blksize).toBe(4096); + expect(stat.blocks).toBe(1); + expect(stat.nlink).toBe(1); + }); +}); From 5933fc5d80329b6b4dfadb16f0a2ba0c215c71b6 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Thu, 26 May 2022 14:54:02 +1000 Subject: [PATCH 54/74] tests: fix for nodesClaim test TypeError --- tests/client/service/nodesClaim.test.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/client/service/nodesClaim.test.ts b/tests/client/service/nodesClaim.test.ts index bee8c8ad3..bc04e2ae6 100644 --- a/tests/client/service/nodesClaim.test.ts +++ b/tests/client/service/nodesClaim.test.ts @@ -15,7 +15,6 @@ import NodeGraph from '@/nodes/NodeGraph'; import NodeManager from '@/nodes/NodeManager'; import Sigchain from '@/sigchain/Sigchain'; import Proxy from '@/network/Proxy'; - import GRPCServer from '@/grpc/GRPCServer'; import GRPCClientClient from '@/client/GRPCClientClient'; import nodesClaim from '@/client/service/nodesClaim'; @@ -26,7 +25,6 @@ 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, [ @@ -63,7 +61,7 @@ describe('nodesClaim', () => { mockedSendNotification = jest .spyOn(NotificationsManager.prototype, 'sendNotification') .mockResolvedValue(undefined); - mockedSendNotification = jest + mockedClaimNode = jest .spyOn(NodeManager.prototype, 'claimNode') .mockResolvedValue(undefined); }); @@ -83,7 +81,6 @@ describe('nodesClaim', () => { let acl: ACL; let sigchain: Sigchain; let proxy: Proxy; - let db: DB; let keyManager: KeyManager; let grpcServer: GRPCServer; @@ -231,7 +228,7 @@ describe('nodesClaim', () => { test('cannot claim an invalid node', async () => { const request = new nodesPB.Claim(); request.setNodeId('nodeId'); - await expectRemoteError( + await testUtils.expectRemoteError( grpcClient.nodesClaim( request, clientUtils.encodeAuthFromPassword(password), From 246dd3a184c60c66de131cb5b7d9b8532b6b1b1e Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Thu, 26 May 2022 18:02:11 +1000 Subject: [PATCH 55/74] tests: fixing timeouts for tests failing in CI/CD --- tests/bin/identities/trustUntrustList.test.ts | 472 +++++++++--------- tests/nodes/NodeConnection.test.ts | 4 +- tests/vaults/VaultManager.test.ts | 220 ++++---- 3 files changed, 355 insertions(+), 341 deletions(-) diff --git a/tests/bin/identities/trustUntrustList.test.ts b/tests/bin/identities/trustUntrustList.test.ts index 5fb91633d..4f0816cbe 100644 --- a/tests/bin/identities/trustUntrustList.test.ts +++ b/tests/bin/identities/trustUntrustList.test.ts @@ -106,248 +106,256 @@ describe('trust/untrust/list', () => { mockedGenerateKeyPair.mockRestore(); mockedGenerateDeterministicKeyPair.mockRestore(); }); - test('trusts and untrusts a gestalt by node, adds it to the gestalt graph, and lists the gestalt with notify permission', async () => { - let exitCode, stdout; - // Add the node to our node graph and authenticate an identity on the - // provider - // This allows us to contact the members of the gestalt we want to trust - await testBinUtils.pkStdio( - [ - 'nodes', - 'add', - nodesUtils.encodeNodeId(nodeId), - nodeHost, - `${nodePort}`, - ], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - ); - const mockedBrowser = jest - .spyOn(identitiesUtils, 'browser') - .mockImplementation(() => {}); - await testBinUtils.pkStdio( - [ - 'identities', - 'authenticate', - testToken.providerId, - testToken.identityId, - ], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - ); - mockedBrowser.mockRestore(); - // Trust node - this should trigger discovery on the gestalt the node - // belongs to and add it to our gestalt graph - ({ exitCode } = await testBinUtils.pkStdio( - ['identities', 'trust', nodesUtils.encodeNodeId(nodeId)], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - // Since discovery is a background process we need to wait for the - // gestalt to be discovered - await pkAgent.discovery.waitForDrained(); - // Check that gestalt was discovered and permission was set - ({ exitCode, stdout } = await testBinUtils.pkStdio( - ['identities', 'list', '--format', 'json'], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toHaveLength(1); - expect(JSON.parse(stdout)[0]).toEqual({ - permissions: ['notify'], - nodes: [{ id: nodesUtils.encodeNodeId(nodeId) }], - identities: [ + test( + 'trusts and untrusts a gestalt by node, adds it to the gestalt graph, and lists the gestalt with notify permission', + async () => { + let exitCode, stdout; + // Add the node to our node graph and authenticate an identity on the + // provider + // This allows us to contact the members of the gestalt we want to trust + await testBinUtils.pkStdio( + [ + 'nodes', + 'add', + nodesUtils.encodeNodeId(nodeId), + nodeHost, + `${nodePort}`, + ], { - providerId: provider.id, - identityId: identity, + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, }, - ], - }); - // Untrust the gestalt by node - // This should remove the permission, but not the gestalt (from the gestalt - // graph) - ({ exitCode } = await testBinUtils.pkStdio( - ['identities', 'untrust', nodesUtils.encodeNodeId(nodeId)], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - // Check that gestalt still exists but has no permissions - ({ exitCode, stdout } = await testBinUtils.pkStdio( - ['identities', 'list', '--format', 'json'], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toHaveLength(1); - expect(JSON.parse(stdout)[0]).toEqual({ - permissions: null, - nodes: [{ id: nodesUtils.encodeNodeId(nodeId) }], - identities: [ + dataDir, + ); + const mockedBrowser = jest + .spyOn(identitiesUtils, 'browser') + .mockImplementation(() => {}); + await testBinUtils.pkStdio( + [ + 'identities', + 'authenticate', + testToken.providerId, + testToken.identityId, + ], { - providerId: provider.id, - identityId: identity, + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, }, - ], - }); - // Revert side-effects - await pkAgent.gestaltGraph.unsetNode(nodeId); - await pkAgent.gestaltGraph.unsetIdentity(provider.id, identity); - await pkAgent.nodeGraph.unsetNode(nodeId); - await pkAgent.identitiesManager.delToken( - testToken.providerId, - testToken.identityId, - ); - // @ts-ignore - get protected property - pkAgent.discovery.visitedVertices.clear(); - }); - test('trusts and untrusts a gestalt by identity, adds it to the gestalt graph, and lists the gestalt with notify permission', async () => { - let exitCode, stdout; - // Add the node to our node graph and authenticate an identity on the - // provider - // This allows us to contact the members of the gestalt we want to trust - await testBinUtils.pkStdio( - [ - 'nodes', - 'add', - nodesUtils.encodeNodeId(nodeId), - nodeHost, - `${nodePort}`, - ], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - ); - const mockedBrowser = jest - .spyOn(identitiesUtils, 'browser') - .mockImplementation(() => {}); - await testBinUtils.pkStdio( - [ - 'identities', - 'authenticate', + dataDir, + ); + mockedBrowser.mockRestore(); + // Trust node - this should trigger discovery on the gestalt the node + // belongs to and add it to our gestalt graph + ({ exitCode } = await testBinUtils.pkStdio( + ['identities', 'trust', nodesUtils.encodeNodeId(nodeId)], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(0); + // Since discovery is a background process we need to wait for the + // gestalt to be discovered + await pkAgent.discovery.waitForDrained(); + // Check that gestalt was discovered and permission was set + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['identities', 'list', '--format', 'json'], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toHaveLength(1); + expect(JSON.parse(stdout)[0]).toEqual({ + permissions: ['notify'], + nodes: [{ id: nodesUtils.encodeNodeId(nodeId) }], + identities: [ + { + providerId: provider.id, + identityId: identity, + }, + ], + }); + // Untrust the gestalt by node + // This should remove the permission, but not the gestalt (from the gestalt + // graph) + ({ exitCode } = await testBinUtils.pkStdio( + ['identities', 'untrust', nodesUtils.encodeNodeId(nodeId)], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(0); + // Check that gestalt still exists but has no permissions + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['identities', 'list', '--format', 'json'], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toHaveLength(1); + expect(JSON.parse(stdout)[0]).toEqual({ + permissions: null, + nodes: [{ id: nodesUtils.encodeNodeId(nodeId) }], + identities: [ + { + providerId: provider.id, + identityId: identity, + }, + ], + }); + // Revert side-effects + await pkAgent.gestaltGraph.unsetNode(nodeId); + await pkAgent.gestaltGraph.unsetIdentity(provider.id, identity); + await pkAgent.nodeGraph.unsetNode(nodeId); + await pkAgent.identitiesManager.delToken( testToken.providerId, testToken.identityId, - ], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - ); - mockedBrowser.mockRestore(); - // Trust identity - this should trigger discovery on the gestalt the node - // belongs to and add it to our gestalt graph - // This command should fail first time as we need to allow time for the - // identity to be linked to a node in the node graph - ({ exitCode } = await testBinUtils.pkStdio( - ['identities', 'trust', providerString], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(sysexits.NOUSER); - // Since discovery is a background process we need to wait for the - // gestalt to be discovered - await pkAgent.discovery.waitForDrained(); - // This time the command should succeed - ({ exitCode } = await testBinUtils.pkStdio( - ['identities', 'trust', providerString], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - // Check that gestalt was discovered and permission was set - ({ exitCode, stdout } = await testBinUtils.pkStdio( - ['identities', 'list', '--format', 'json'], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toHaveLength(1); - expect(JSON.parse(stdout)[0]).toEqual({ - permissions: ['notify'], - nodes: [{ id: nodesUtils.encodeNodeId(nodeId) }], - identities: [ + ); + // @ts-ignore - get protected property + pkAgent.discovery.visitedVertices.clear(); + }, + global.defaultTimeout * 2, + ); + test( + 'trusts and untrusts a gestalt by identity, adds it to the gestalt graph, and lists the gestalt with notify permission', + async () => { + let exitCode, stdout; + // Add the node to our node graph and authenticate an identity on the + // provider + // This allows us to contact the members of the gestalt we want to trust + await testBinUtils.pkStdio( + [ + 'nodes', + 'add', + nodesUtils.encodeNodeId(nodeId), + nodeHost, + `${nodePort}`, + ], { - providerId: provider.id, - identityId: identity, + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, }, - ], - }); - // Untrust the gestalt by node - // This should remove the permission, but not the gestalt (from the gestalt - // graph) - ({ exitCode } = await testBinUtils.pkStdio( - ['identities', 'untrust', providerString], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - // Check that gestalt still exists but has no permissions - ({ exitCode, stdout } = await testBinUtils.pkStdio( - ['identities', 'list', '--format', 'json'], - { - PK_NODE_PATH: nodePath, - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toHaveLength(1); - expect(JSON.parse(stdout)[0]).toEqual({ - permissions: null, - nodes: [{ id: nodesUtils.encodeNodeId(nodeId) }], - identities: [ + dataDir, + ); + const mockedBrowser = jest + .spyOn(identitiesUtils, 'browser') + .mockImplementation(() => {}); + await testBinUtils.pkStdio( + [ + 'identities', + 'authenticate', + testToken.providerId, + testToken.identityId, + ], { - providerId: provider.id, - identityId: identity, + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, }, - ], - }); - // Revert side-effects - await pkAgent.gestaltGraph.unsetNode(nodeId); - await pkAgent.gestaltGraph.unsetIdentity(provider.id, identity); - await pkAgent.nodeGraph.unsetNode(nodeId); - await pkAgent.identitiesManager.delToken( - testToken.providerId, - testToken.identityId, - ); - // @ts-ignore - get protected property - pkAgent.discovery.visitedVertices.clear(); - }); + dataDir, + ); + mockedBrowser.mockRestore(); + // Trust identity - this should trigger discovery on the gestalt the node + // belongs to and add it to our gestalt graph + // This command should fail first time as we need to allow time for the + // identity to be linked to a node in the node graph + ({ exitCode } = await testBinUtils.pkStdio( + ['identities', 'trust', providerString], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(sysexits.NOUSER); + // Since discovery is a background process we need to wait for the + // gestalt to be discovered + await pkAgent.discovery.waitForDrained(); + // This time the command should succeed + ({ exitCode } = await testBinUtils.pkStdio( + ['identities', 'trust', providerString], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(0); + // Check that gestalt was discovered and permission was set + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['identities', 'list', '--format', 'json'], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toHaveLength(1); + expect(JSON.parse(stdout)[0]).toEqual({ + permissions: ['notify'], + nodes: [{ id: nodesUtils.encodeNodeId(nodeId) }], + identities: [ + { + providerId: provider.id, + identityId: identity, + }, + ], + }); + // Untrust the gestalt by node + // This should remove the permission, but not the gestalt (from the gestalt + // graph) + ({ exitCode } = await testBinUtils.pkStdio( + ['identities', 'untrust', providerString], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(0); + // Check that gestalt still exists but has no permissions + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['identities', 'list', '--format', 'json'], + { + PK_NODE_PATH: nodePath, + PK_PASSWORD: password, + }, + dataDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toHaveLength(1); + expect(JSON.parse(stdout)[0]).toEqual({ + permissions: null, + nodes: [{ id: nodesUtils.encodeNodeId(nodeId) }], + identities: [ + { + providerId: provider.id, + identityId: identity, + }, + ], + }); + // Revert side-effects + await pkAgent.gestaltGraph.unsetNode(nodeId); + await pkAgent.gestaltGraph.unsetIdentity(provider.id, identity); + await pkAgent.nodeGraph.unsetNode(nodeId); + await pkAgent.identitiesManager.delToken( + testToken.providerId, + testToken.identityId, + ); + // @ts-ignore - get protected property + pkAgent.discovery.visitedVertices.clear(); + }, + global.defaultTimeout * 2, + ); test('should fail on invalid inputs', async () => { let exitCode; // Trust diff --git a/tests/nodes/NodeConnection.test.ts b/tests/nodes/NodeConnection.test.ts index 7c842724d..ed80ab06a 100644 --- a/tests/nodes/NodeConnection.test.ts +++ b/tests/nodes/NodeConnection.test.ts @@ -60,7 +60,7 @@ const mockedGenerateDeterministicKeyPair = jest.spyOn( 'generateDeterministicKeyPair', ); -describe(`${NodeConnection.name} test`, () => { +describe('${NodeConnection.name} test', () => { const logger = new Logger(`${NodeConnection.name} test`, LogLevel.WARN, [ new StreamHandler(), ]); @@ -767,6 +767,7 @@ describe(`${NodeConnection.name} test`, () => { await nodeConnection?.destroy(); } }, + global.defaultTimeout * 2, ); test.each(options)( "should call `killSelf and throw if the server %s's during testStreamFail", @@ -839,5 +840,6 @@ describe(`${NodeConnection.name} test`, () => { await nodeConnection?.destroy(); } }, + global.defaultTimeout * 2, ); }); diff --git a/tests/vaults/VaultManager.test.ts b/tests/vaults/VaultManager.test.ts index 783de4ef4..e4ed618aa 100644 --- a/tests/vaults/VaultManager.test.ts +++ b/tests/vaults/VaultManager.test.ts @@ -1252,120 +1252,124 @@ describe('VaultManager', () => { await vaultManager?.destroy(); } }); - test('pullVault respects locking', async () => { - // This should respect the VaultManager read lock - // and the VaultInternal write lock - const vaultManager = await VaultManager.createVaultManager({ - vaultsPath, - keyManager: dummyKeyManager, - gestaltGraph: {} as GestaltGraph, - nodeConnectionManager, - acl: {} as ACL, - notificationsManager: {} as NotificationsManager, - db, - logger: logger.getChild(VaultManager.name), - }); - const pullVaultMock = jest.spyOn(VaultInternal.prototype, 'pullVault'); - const gitPullMock = jest.spyOn(git, 'pull'); - try { - // Creating some state at the remote - await remoteKeynode1.vaultManager.withVaults( - [remoteVaultId], - async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile('secret-1', 'secret1'); - await efs.writeFile('secret-2', 'secret2'); - }); - }, - ); - - // Setting permissions - await remoteKeynode1.gestaltGraph.setNode({ - id: localNodeIdEncoded, - chain: {}, + test( + 'pullVault respects locking', + async () => { + // This should respect the VaultManager read lock + // and the VaultInternal write lock + const vaultManager = await VaultManager.createVaultManager({ + vaultsPath, + keyManager: dummyKeyManager, + gestaltGraph: {} as GestaltGraph, + nodeConnectionManager, + acl: {} as ACL, + notificationsManager: {} as NotificationsManager, + db, + logger: logger.getChild(VaultManager.name), }); - await remoteKeynode1.gestaltGraph.setGestaltActionByNode( - localNodeId, - 'scan', - ); - await remoteKeynode1.acl.setVaultAction( - remoteVaultId, - localNodeId, - 'clone', - ); - await remoteKeynode1.acl.setVaultAction( - remoteVaultId, - localNodeId, - 'pull', - ); + const pullVaultMock = jest.spyOn(VaultInternal.prototype, 'pullVault'); + const gitPullMock = jest.spyOn(git, 'pull'); + try { + // Creating some state at the remote + await remoteKeynode1.vaultManager.withVaults( + [remoteVaultId], + async (vault) => { + await vault.writeF(async (efs) => { + await efs.writeFile('secret-1', 'secret1'); + await efs.writeFile('secret-2', 'secret2'); + }); + }, + ); - await vaultManager.cloneVault(remoteKeynode1Id, vaultName); - const vaultId = await vaultManager.getVaultId(vaultName); - if (vaultId === undefined) fail('VaultId is not found.'); + // Setting permissions + await remoteKeynode1.gestaltGraph.setNode({ + id: localNodeIdEncoded, + chain: {}, + }); + await remoteKeynode1.gestaltGraph.setGestaltActionByNode( + localNodeId, + 'scan', + ); + await remoteKeynode1.acl.setVaultAction( + remoteVaultId, + localNodeId, + 'clone', + ); + await remoteKeynode1.acl.setVaultAction( + remoteVaultId, + localNodeId, + 'pull', + ); - // Creating new history - await remoteKeynode1.vaultManager.withVaults( - [remoteVaultId], - async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile('secret-2', 'secret2'); - }); - }, - ); + await vaultManager.cloneVault(remoteKeynode1Id, vaultName); + const vaultId = await vaultManager.getVaultId(vaultName); + if (vaultId === undefined) fail('VaultId is not found.'); - // @ts-ignore: kidnap vaultManager map and grabbing lock - const vaultsMap = vaultManager.vaultMap; - const vault = vaultsMap.get(vaultId.toString() as VaultIdString); - // @ts-ignore: kidnap vaultManager lockBox - const vaultLocks = vaultManager.vaultLocks; - const [releaseWrite] = await vaultLocks.lock([ - vaultId, - RWLockWriter, - 'write', - ])(); - - // Pulling vault respects VaultManager write lock - const pullP = vaultManager.pullVault({ - vaultId: vaultId, - }); - await sleep(200); - expect(pullVaultMock).not.toHaveBeenCalled(); - await releaseWrite(); - await pullP; - expect(pullVaultMock).toHaveBeenCalled(); - pullVaultMock.mockClear(); + // Creating new history + await remoteKeynode1.vaultManager.withVaults( + [remoteVaultId], + async (vault) => { + await vault.writeF(async (efs) => { + await efs.writeFile('secret-2', 'secret2'); + }); + }, + ); - // Creating new history - await remoteKeynode1.vaultManager.withVaults( - [remoteVaultId], - async (vault) => { - await vault.writeF(async (efs) => { - await efs.writeFile('secret-3', 'secret3'); - }); - }, - ); + // @ts-ignore: kidnap vaultManager map and grabbing lock + const vaultsMap = vaultManager.vaultMap; + const vault = vaultsMap.get(vaultId.toString() as VaultIdString); + // @ts-ignore: kidnap vaultManager lockBox + const vaultLocks = vaultManager.vaultLocks; + const [releaseWrite] = await vaultLocks.lock([ + vaultId, + RWLockWriter, + 'write', + ])(); + + // Pulling vault respects VaultManager write lock + const pullP = vaultManager.pullVault({ + vaultId: vaultId, + }); + await sleep(200); + expect(pullVaultMock).not.toHaveBeenCalled(); + await releaseWrite(); + await pullP; + expect(pullVaultMock).toHaveBeenCalled(); + pullVaultMock.mockClear(); + + // Creating new history + await remoteKeynode1.vaultManager.withVaults( + [remoteVaultId], + async (vault) => { + await vault.writeF(async (efs) => { + await efs.writeFile('secret-3', 'secret3'); + }); + }, + ); - // Respects VaultInternal write lock - // @ts-ignore: kidnap vault lock - const vaultLock = vault!.lock; - const [releaseVaultWrite] = await vaultLock.write()(); - // Pulling vault respects VaultManager write lock - gitPullMock.mockClear(); - const pullP2 = vaultManager.pullVault({ - vaultId: vaultId, - }); - await sleep(200); - expect(gitPullMock).not.toHaveBeenCalled(); - await releaseVaultWrite(); - await pullP2; - expect(gitPullMock).toHaveBeenCalled(); - } finally { - pullVaultMock.mockRestore(); - gitPullMock.mockRestore(); - await vaultManager?.stop(); - await vaultManager?.destroy(); - } - }); + // Respects VaultInternal write lock + // @ts-ignore: kidnap vault lock + const vaultLock = vault!.lock; + const [releaseVaultWrite] = await vaultLock.write()(); + // Pulling vault respects VaultManager write lock + gitPullMock.mockClear(); + const pullP2 = vaultManager.pullVault({ + vaultId: vaultId, + }); + await sleep(200); + expect(gitPullMock).not.toHaveBeenCalled(); + await releaseVaultWrite(); + await pullP2; + expect(gitPullMock).toHaveBeenCalled(); + } finally { + pullVaultMock.mockRestore(); + gitPullMock.mockRestore(); + await vaultManager?.stop(); + await vaultManager?.destroy(); + } + }, + global.failedConnectionTimeout, + ); }); test('handleScanVaults should list all vaults with permissions', async () => { // 1. we need to set up state From ad9b51b81943d0a3c3d5bf8923431bc6b075b1e0 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Fri, 27 May 2022 15:09:36 +1000 Subject: [PATCH 56/74] feat: updating `@matrixai/db` to `^4.0.1` Had to fix the usage in 5 domains. --- package-lock.json | 85 +++++++++++++++++++++-- package.json | 2 +- src/acl/ACL.ts | 14 ++-- src/discovery/Discovery.ts | 17 +++-- src/nodes/NodeGraph.ts | 13 ++-- src/notifications/NotificationsManager.ts | 8 ++- src/sigchain/Sigchain.ts | 30 ++++---- 7 files changed, 124 insertions(+), 45 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1ef8456e6..21870372a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@grpc/grpc-js": "1.6.7", "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.4", - "@matrixai/db": "^3.3.3", + "@matrixai/db": "^4.0.1", "@matrixai/errors": "^1.1.1", "@matrixai/id": "^3.3.3", "@matrixai/logger": "^2.1.1", @@ -83,6 +83,47 @@ "typescript-cached-transpile": "0.0.6" } }, + "../js-db": { + "name": "@matrixai/db", + "version": "4.0.1", + "extraneous": true, + "license": "Apache-2.0", + "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" + }, + "devDependencies": { + "@types/jest": "^27.0.2", + "@types/level": "^6.0.0", + "@types/node": "^16.11.7", + "@types/node-forge": "^0.10.4", + "@typescript-eslint/eslint-plugin": "^5.23.0", + "@typescript-eslint/parser": "^5.23.0", + "benny": "^3.6.15", + "eslint": "^8.15.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-prettier": "^4.0.0", + "jest": "^27.2.5", + "jest-junit": "^13.2.0", + "lexicographic-integer": "^1.1.0", + "node-forge": "^1.3.1", + "prettier": "^2.6.2", + "rimraf": "^3.0.2", + "systeminformation": "^5.8.9", + "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", @@ -2524,9 +2565,9 @@ } }, "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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.1.tgz", + "integrity": "sha512-pgW0LXdMqx7daOxByP9Y1T0BGOi4wC8oME4wS21nOVOYV/Ht3Zf0ogfkfzaB/nD4m7x90TamwMK8TeUI5mxdaw==", "dependencies": { "@matrixai/async-init": "^1.7.3", "@matrixai/errors": "^1.1.1", @@ -4580,6 +4621,21 @@ "util-callbackify": "^1.0.0" } }, + "node_modules/encryptedfs/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/encryptedfs/node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -13461,9 +13517,9 @@ } }, "@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==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.1.tgz", + "integrity": "sha512-pgW0LXdMqx7daOxByP9Y1T0BGOi4wC8oME4wS21nOVOYV/Ht3Zf0ogfkfzaB/nD4m7x90TamwMK8TeUI5mxdaw==", "requires": { "@matrixai/async-init": "^1.7.3", "@matrixai/errors": "^1.1.1", @@ -15071,6 +15127,21 @@ "util-callbackify": "^1.0.0" }, "dependencies": { + "@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==", + "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", + "threads": "^1.6.5" + } + }, "node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", diff --git a/package.json b/package.json index 8f6197450..203eb5b7e 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@grpc/grpc-js": "1.6.7", "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.4", - "@matrixai/db": "^3.3.3", + "@matrixai/db": "^4.0.1", "@matrixai/errors": "^1.1.1", "@matrixai/id": "^3.3.3", "@matrixai/logger": "^2.1.1", diff --git a/src/acl/ACL.ts b/src/acl/ACL.ts index e97dc6c30..caa308f13 100644 --- a/src/acl/ACL.ts +++ b/src/acl/ACL.ts @@ -135,11 +135,12 @@ class ACL { return this.withTransactionF(async (tran) => this.getNodePerms(tran)); } const permIds: Record> = {}; - for await (const [k, v] of tran.iterator(undefined, [ + for await (const [keyPath, value] of tran.iterator(undefined, [ ...this.aclNodesDbPath, ])) { - const nodeId = IdInternal.fromBuffer(k); - const permId = IdInternal.fromBuffer(v); + const key = keyPath[0] as Buffer; + const nodeId = IdInternal.fromBuffer(key); + const permId = IdInternal.fromBuffer(value); let nodePerm: Record; if (permId in permIds) { nodePerm = permIds[permId]; @@ -175,11 +176,12 @@ class ACL { return this.withTransactionF(async (tran) => this.getVaultPerms(tran)); } const vaultPerms: Record> = {}; - for await (const [k, v] of tran.iterator(undefined, [ + for await (const [keyPath, value] of tran.iterator(undefined, [ ...this.aclVaultsDbPath, ])) { - const vaultId = IdInternal.fromBuffer(k); - const nodeIds = dbUtils.deserialize>(v); + const key = keyPath[0] as Buffer; + const vaultId = IdInternal.fromBuffer(key); + const nodeIds = dbUtils.deserialize>(value); const nodePerm: Record = {}; const nodeIdsGc: Set = new Set(); for (const nodeIdString in nodeIds) { diff --git a/src/discovery/Discovery.ts b/src/discovery/Discovery.ts index 53026b098..576ecf29f 100644 --- a/src/discovery/Discovery.ts +++ b/src/discovery/Discovery.ts @@ -26,7 +26,7 @@ import { 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 { utils as dbUtils } from '@matrixai/db'; import * as resources from '@matrixai/resources'; import * as discoveryUtils from './utils'; import * as discoveryErrors from './errors'; @@ -134,7 +134,8 @@ class Discovery { { limit: 1, reverse: true, values: false }, this.discoveryQueueDbPath, ); - for await (const [key] of keyIterator) { + for await (const [keyPath] of keyIterator) { + const key = keyPath[0] as Buffer; latestId = IdInternal.fromBuffer(key); } this.discoveryQueueIdGenerator = @@ -202,12 +203,13 @@ class Discovery { // Processing queue this.logger.debug('DiscoveryQueue is processing'); - for await (const [key, value] of this.db.iterator( + for await (const [keyPath, value] of this.db.iterator( {}, this.discoveryQueueDbPath, )) { - const vertexId = IdInternal.fromBuffer(key) as DiscoveryQueueId; - const vertex = DBUtils.deserialize(value); + const key = keyPath[0] as Buffer; + const vertexId = IdInternal.fromBuffer(key); + const vertex = dbUtils.deserialize(value); this.logger.debug(`Processing vertex: ${vertex}`); const vertexGId = gestaltsUtils.ungestaltKey(vertex); switch (vertexGId.type) { @@ -424,10 +426,11 @@ class Discovery { return await this.lock.withF(async () => { let nextDiscoveryQueueId: DiscoveryQueueId | undefined; const keyIterator = this.db.iterator( - { limit: 1 }, + { limit: 1, values: false }, this.discoveryQueueDbPath, ); - for await (const [key] of keyIterator) { + for await (const [keyPath] of keyIterator) { + const key = keyPath[0] as Buffer; nextDiscoveryQueueId = IdInternal.fromBuffer(key); } return nextDiscoveryQueueId == null; diff --git a/src/nodes/NodeGraph.ts b/src/nodes/NodeGraph.ts index ddf2ff7b3..31cc5d130 100644 --- a/src/nodes/NodeGraph.ts +++ b/src/nodes/NodeGraph.ts @@ -1,7 +1,8 @@ import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; -import type { NodeId, NodeAddress, NodeBucket } from './types'; +import type { NodeAddress, NodeBucket, NodeId } from './types'; import type KeyManager from '../keys/KeyManager'; import type { Host, Hostname, Port } from '../network/types'; +import { utils as dbUtils } from '@matrixai/db'; import lexi from 'lexicographic-integer'; import Logger from '@matrixai/logger'; import { @@ -9,7 +10,6 @@ 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'; @@ -335,14 +335,11 @@ class NodeGraph { // 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 }, [ + for await (const [keyPath] of tran.iterator({ values: false }, [ ...this.nodeGraphBucketsDbPath, ])) { - const hexBucketIndex = k.toString(); - const hexBucketPath = [ - ...this.nodeGraphBucketsDbPath, - hexBucketIndex, - ] as unknown as KeyPath; + const key = keyPath[0].toString(); + const hexBucketPath = [...this.nodeGraphBucketsDbPath, key]; await tran.del(hexBucketPath); } const tempBuckets: Record = {}; diff --git a/src/notifications/NotificationsManager.ts b/src/notifications/NotificationsManager.ts index dce39dd16..58b6fc42c 100644 --- a/src/notifications/NotificationsManager.ts +++ b/src/notifications/NotificationsManager.ts @@ -140,10 +140,11 @@ class NotificationsManager { // Getting latest ID and creating ID generator let latestId: NotificationId | undefined; const keyIterator = tran.iterator( - { limit: 1, reverse: true }, + { limit: 1, reverse: true, values: false }, this.notificationsMessagesDbPath, ); - for await (const [key] of keyIterator) { + for await (const [keyPath] of keyIterator) { + const key = keyPath[0] as Buffer; latestId = IdInternal.fromBuffer(key); } this.notificationIdGenerator = @@ -367,7 +368,8 @@ class NotificationsManager { ): Promise> { const notificationIds: Array = []; const messageIterator = tran.iterator({}, this.notificationsMessagesDbPath); - for await (const [key, value] of messageIterator) { + for await (const [keyPath, value] of messageIterator) { + const key = keyPath[0] as Buffer; const notificationId = IdInternal.fromBuffer(key); const notification = JSON.parse(value.toString()) as Notification; if (type === 'all') { diff --git a/src/sigchain/Sigchain.ts b/src/sigchain/Sigchain.ts index 25614e490..a2a1f0af4 100644 --- a/src/sigchain/Sigchain.ts +++ b/src/sigchain/Sigchain.ts @@ -10,13 +10,13 @@ import type { } from '../claims/types'; import type KeyManager from '../keys/KeyManager'; import type { NodeIdEncoded } from '../nodes/types'; +import { utils as dbUtils } from '@matrixai/db'; 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 { Lock, LockBox } from '@matrixai/async-locks'; import { withF } from '@matrixai/resources'; import * as sigchainErrors from './errors'; @@ -269,11 +269,10 @@ class Sigchain { seq: (await this.getSequenceNumber(tran)) + 1, data: claimData, }); - const intermediaryClaim: ClaimIntermediary = { + return { payload: claim.payload, signature: claim.signatures[0], }; - return intermediaryClaim; } /** @@ -289,10 +288,11 @@ class Sigchain { } const chainData: ChainDataEncoded = {}; const readIterator = tran.iterator({}, [...this.sigchainClaimsDbPath]); - for await (const [key, value] of readIterator) { + for await (const [keyPath, value] of readIterator) { + const key = keyPath[0] as Buffer; const claimId = IdInternal.fromBuffer(key); - const claim = dbUtils.deserialize(value); - chainData[claimsUtils.encodeClaimId(claimId)] = claim; + chainData[claimsUtils.encodeClaimId(claimId)] = + dbUtils.deserialize(value); } return chainData; } @@ -399,9 +399,12 @@ class Sigchain { return this.withTransactionF(async (tran) => this.getSeqMap(tran)); } const map: Record = {}; - const claimStream = tran.iterator({}, [...this.sigchainClaimsDbPath]); + const claimStream = tran.iterator({ values: false }, [ + ...this.sigchainClaimsDbPath, + ]); let seq = 1; - for await (const [key] of claimStream) { + for await (const [keyPath] of claimStream) { + const key = keyPath[0] as Buffer; map[seq] = IdInternal.fromBuffer(key); seq++; } @@ -412,11 +415,12 @@ class Sigchain { 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); + const keyStream = tran.iterator( + { limit: 1, reverse: true, values: false }, + [...this.sigchainClaimsDbPath], + ); + for await (const [keyPath] of keyStream) { + latestId = IdInternal.fromBuffer(keyPath[0] as Buffer); } return latestId; } From 36abd2948664af6cd2d4a9af072721d059e9aaab Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Wed, 25 May 2022 16:51:02 +1000 Subject: [PATCH 57/74] tests: general clean up for proxy tests --- package-lock.json | 44 ++--- tests/network/Proxy.test.ts | 311 +++++++++++++++--------------------- tests/network/utils.test.ts | 4 +- 3 files changed, 156 insertions(+), 203 deletions(-) diff --git a/package-lock.json b/package-lock.json index 21870372a..02a32f2c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2655,7 +2655,7 @@ "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", @@ -2670,12 +2670,12 @@ "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -2684,27 +2684,27 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "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=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@sinonjs/commons": { "version": "1.8.3", @@ -9918,9 +9918,9 @@ } }, "node_modules/protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -13598,7 +13598,7 @@ "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "@protobufjs/base64": { "version": "1.1.2", @@ -13613,12 +13613,12 @@ "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -13627,27 +13627,27 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "@sinonjs/commons": { "version": "1.8.3", @@ -19122,9 +19122,9 @@ } }, "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", diff --git a/tests/network/Proxy.test.ts b/tests/network/Proxy.test.ts index b418d6544..b9a7d6e50 100644 --- a/tests/network/Proxy.test.ts +++ b/tests/network/Proxy.test.ts @@ -6,12 +6,12 @@ import http from 'http'; import tls from 'tls'; import UTP from 'utp-native'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; -import { poll, promise, promisify, timerStart, timerStop } from '@/utils'; 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 { promisify, promise, timerStart, timerStop, poll } from '@/utils'; import * as testUtils from '../utils'; /** @@ -107,7 +107,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.DEBUG, [ + const logger = new Logger(`${Proxy.name} test`, LogLevel.WARN, [ new StreamHandler(), ]); const nodeIdABC = testUtils.generateRandomNodeId(); @@ -249,7 +249,7 @@ describe(Proxy.name, () => { }); // Cannot open connection to port 0 await expect(() => - proxy.openConnectionForward(nodeIdABC, '127.0.0.1' as Host, 0 as Port), + proxy.openConnectionForward(nodeIdABC, localHost, 0 as Port), ).rejects.toThrow(networkErrors.ErrorConnectionStart); await expect(() => httpConnect( @@ -282,35 +282,35 @@ describe(Proxy.name, () => { serverPort: port, }); // This UTP server will just hang and not respond - let recievedCount = 0; + let receivedCount = 0; const utpSocketHang = UTP.createServer(() => { - recievedCount++; + receivedCount++; }); const utpSocketHangListen = promisify(utpSocketHang.listen).bind( utpSocketHang, ); - await utpSocketHangListen(0, '127.0.0.1'); + await utpSocketHangListen(0, localHost); const utpSocketHangPort = utpSocketHang.address().port; await expect(() => proxy.openConnectionForward( nodeIdABC, - '127.0.0.1' as Host, + localHost, utpSocketHangPort as Port, ), ).rejects.toThrow(networkErrors.ErrorConnectionStartTimeout); - expect(recievedCount).toBe(1); + expect(receivedCount).toBe(1); // Can override the timer const timer = timerStart(2000); await expect(() => proxy.openConnectionForward( nodeIdABC, - '127.0.0.1' as Host, + localHost, utpSocketHangPort as Port, timer, ), ).rejects.toThrow(networkErrors.ErrorConnectionStartTimeout); timerStop(timer); - expect(recievedCount).toBe(2); + expect(receivedCount).toBe(2); await expect(() => httpConnect( proxy.getForwardHost(), @@ -321,7 +321,7 @@ describe(Proxy.name, () => { )}`, ), ).rejects.toThrow('504'); - expect(recievedCount).toBe(3); + expect(receivedCount).toBe(3); utpSocketHang.close(); utpSocketHang.unref(); await proxy.stop(); @@ -341,34 +341,34 @@ describe(Proxy.name, () => { }); // This UTP Server will immediately end and destroy // the connection upon receiving a connection - let recievedCount = 0; + let receivedCount = 0; const utpSocketEnd = UTP.createServer((utpConn) => { - recievedCount++; + receivedCount++; utpConn.end(); utpConn.destroy(); }); const utpSocketEndListen = promisify(utpSocketEnd.listen).bind( utpSocketEnd, ); - await utpSocketEndListen(0, '127.0.0.1'); + await utpSocketEndListen(0, localHost); const utpSocketEndPort = utpSocketEnd.address().port; await expect(() => proxy.openConnectionForward( nodeIdABC, - '127.0.0.1' as Host, + localHost, utpSocketEndPort as Port, ), ).rejects.toThrow(networkErrors.ErrorConnectionStart); - expect(recievedCount).toBe(1); + expect(receivedCount).toBe(1); // The actual error is UTP_ECONNRESET to be precise await expect(() => proxy.openConnectionForward( nodeIdABC, - '127.0.0.1' as Host, + localHost, utpSocketEndPort as Port, ), ).rejects.toThrow(/UTP_ECONNRESET/); - expect(recievedCount).toBe(2); + expect(receivedCount).toBe(2); // 502 Bad Gateway on HTTP Connect await expect(() => httpConnect( @@ -380,7 +380,7 @@ describe(Proxy.name, () => { )}`, ), ).rejects.toThrow('502'); - expect(recievedCount).toBe(3); + expect(receivedCount).toBe(3); utpSocketEnd.close(); utpSocketEnd.unref(); await proxy.stop(); @@ -460,7 +460,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -473,19 +473,19 @@ describe(Proxy.name, () => { ), ).rejects.toThrow(networkErrors.ErrorConnectionStart); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); + expect(utpConnError).toHaveBeenCalledTimes(0); // The TLS socket throw an error because there's no suitable signature algorithm - expect(tlsSocketError.mock.calls.length).toBe(1); + expect(tlsSocketError).toHaveBeenCalledTimes(1); // 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).toHaveBeenCalledTimes(0); // 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).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(true); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -566,7 +566,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -582,19 +582,19 @@ describe(Proxy.name, () => { ), ).rejects.toThrow('502'); await expect(remoteClosedP).resolves.toBeUndefined(); - expect(utpConnError.mock.calls.length).toBe(0); + expect(utpConnError).toHaveBeenCalledTimes(0); // The TLS socket throw an error because there's no suitable signature algorithm - expect(tlsSocketError.mock.calls.length).toBe(1); + expect(tlsSocketError).toHaveBeenCalledTimes(1); // 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).toHaveBeenCalledTimes(0); // 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).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(true); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -687,7 +687,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -702,15 +702,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).toHaveBeenCalledTimes(0); // No TLS socket errors this time - // The client side figured that the node id is incorect - expect(tlsSocketError.mock.calls.length).toBe(0); + // The client side figured that the node id is incorrect + expect(tlsSocketError).toHaveBeenCalledTimes(0); // This time the tls socket is ended from the client side - expect(tlsSocketEnd.mock.calls.length).toBe(1); + expect(tlsSocketEnd).toHaveBeenCalledTimes(1); // 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(); @@ -803,7 +803,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -821,15 +821,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).toHaveBeenCalledTimes(0); // 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).toHaveBeenCalledTimes(0); // This time the tls socket is ended from the client side - expect(tlsSocketEnd.mock.calls.length).toBe(1); + expect(tlsSocketEnd).toHaveBeenCalledTimes(1); // 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(); @@ -927,7 +927,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -951,11 +951,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).toHaveBeenCalledTimes(0); + expect(tlsSocketError).toHaveBeenCalledTimes(0); + expect(tlsSocketEnd).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1057,7 +1057,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -1082,7 +1082,7 @@ describe(Proxy.name, () => { tlsSocket_!.once('end', resolveEndP); tlsSocket_!.end(); await endP; - // Force destroy the socket due to buggy tlsSocket and utpConn + // Force destroys the socket due to buggy tlsSocket and utpConn tlsSocket_!.destroy(); logger.debug('Reverse: finishes tlsSocket ending'); await expect(remoteClosedP).resolves.toBeUndefined(); @@ -1093,19 +1093,18 @@ describe(Proxy.name, () => { return proxy.getConnectionForwardCount(); }, (_, result) => { - if (result === 0) return true; - return false; + return result === 0; }, 100, ), ).resolves.toBe(0); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); + expect(utpConnError).toHaveBeenCalledTimes(0); + expect(tlsSocketError).toHaveBeenCalledTimes(0); // 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).toHaveBeenCalledTimes(0); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1204,7 +1203,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -1247,14 +1246,14 @@ describe(Proxy.name, () => { utpSocketPort as Port, ); expect(proxy.getConnectionForwardCount()).toBe(0); - expect(clientSocketEnd.mock.calls.length).toBe(1); + expect(clientSocketEnd).toHaveBeenCalledTimes(1); 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).toHaveBeenCalledTimes(0); + expect(tlsSocketError).toHaveBeenCalledTimes(0); + expect(tlsSocketEnd).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1356,7 +1355,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -1401,11 +1400,11 @@ describe(Proxy.name, () => { tlsSocket_!.once('end', resolveEndP); tlsSocket_!.end(); await endP; - // Force destroy the socket due to buggy tlsSocket and utpConn + // Force destroys the socket due to buggy tlsSocket and utpConn tlsSocket_!.destroy(); logger.debug('Reverse: finishes tlsSocket ending'); await expect(localClosedP).resolves.toBeUndefined(); - expect(clientSocketEnd.mock.calls.length).toBe(1); + expect(clientSocketEnd).toHaveBeenCalledTimes(1); await expect(remoteClosedP).resolves.toBeUndefined(); // Connection count should reach 0 eventually await expect( @@ -1414,19 +1413,18 @@ describe(Proxy.name, () => { return proxy.getConnectionForwardCount(); }, (_, result) => { - if (result === 0) return true; - return false; + return result === 0; }, 100, ), ).resolves.toBe(0); - expect(utpConnError.mock.calls.length).toBe(0); - expect(tlsSocketError.mock.calls.length).toBe(0); + expect(utpConnError).toHaveBeenCalledTimes(0); + expect(tlsSocketError).toHaveBeenCalledTimes(0); // 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).toHaveBeenCalledTimes(0); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1525,7 +1523,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -1554,7 +1552,7 @@ describe(Proxy.name, () => { ); expect(proxy.getConnectionForwardCount()).toBe(1); const { p: endP, resolveP: resolveEndP } = promise(); - // By default net sockets have `allowHalfOpen: false` + // By default, net sockets have `allowHalfOpen: false` // Here we override the behaviour by removing the end listener // And replacing it with our own, and remember to also force destroy clientSocket.removeAllListeners('end'); @@ -1575,17 +1573,16 @@ describe(Proxy.name, () => { return proxy.getConnectionForwardCount(); }, (_, result) => { - if (result === 0) return true; - return false; + return result === 0; }, 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).toHaveBeenCalledTimes(0); + expect(tlsSocketError).toHaveBeenCalledTimes(0); + expect(tlsSocketEnd).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1681,7 +1678,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; await proxy.openConnectionForward( @@ -1712,11 +1709,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).toHaveBeenCalledTimes(0); + expect(tlsSocketError).toHaveBeenCalledTimes(0); + expect(tlsSocketEnd).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1814,7 +1811,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -1829,11 +1826,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).toHaveBeenCalledTimes(0); + expect(tlsSocketError).toHaveBeenCalledTimes(0); + expect(tlsSocketEnd).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -1932,7 +1929,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -1965,17 +1962,16 @@ describe(Proxy.name, () => { return proxy.getConnectionForwardCount(); }, (_, result) => { - if (result === 0) return true; - return false; + return result === 0; }, 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).toHaveBeenCalledTimes(0); + expect(tlsSocketError).toHaveBeenCalledTimes(0); + expect(tlsSocketEnd).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledTimes(1); + expect(tlsSocketClose).toHaveBeenCalledWith(false); utpSocket.off('message', handleMessage); utpSocket.close(); utpSocket.unref(); @@ -2057,7 +2053,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen = promisify(utpSocket.listen).bind(utpSocket); - await utpSocketListen(0, '127.0.0.1'); + await utpSocketListen(0, localHost); const utpSocketHost = utpSocket.address().address; const utpSocketPort = utpSocket.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -2163,7 +2159,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen1 = promisify(utpSocket1.listen).bind(utpSocket1); - await utpSocketListen1(0, '127.0.0.1'); + await utpSocketListen1(0, localHost); const utpSocketHost1 = utpSocket1.address().address; const utpSocketPort1 = utpSocket1.address().port; const utpSocket2 = UTP.createServer(async (utpConn) => { @@ -2206,7 +2202,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketListen2 = promisify(utpSocket2.listen).bind(utpSocket2); - await utpSocketListen2(0, '127.0.0.1'); + await utpSocketListen2(0, localHost); const utpSocketHost2 = utpSocket2.address().address; const utpSocketPort2 = utpSocket2.address().port; expect(proxy.getConnectionForwardCount()).toBe(0); @@ -2242,7 +2238,6 @@ describe(Proxy.name, () => { utpSocket2.unref(); await proxy.stop(); }); - test('open connection to port 0 fails', async () => { const proxy = new Proxy({ logger: logger.getChild('Proxy port 0'), @@ -2267,7 +2262,7 @@ describe(Proxy.name, () => { }, }); await expect( - proxy.openConnectionReverse('127.0.0.1' as Host, 0 as Port), + proxy.openConnectionReverse(localHost, 0 as Port), ).rejects.toThrow(networkErrors.ErrorConnectionStart); await expect(serverConnP).resolves.toBeUndefined(); await expect(serverConnClosedP).resolves.toBeUndefined(); @@ -2300,15 +2295,11 @@ describe(Proxy.name, () => { // This UTP client will just hang and not respond const utpSocket = UTP(); const utpSocketBind = promisify(utpSocket.bind).bind(utpSocket); - await utpSocketBind(0, '127.0.0.1'); + await utpSocketBind(0, localHost); const utpSocketPort = utpSocket.address().port; const timer = timerStart(3000); await expect( - proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - timer, - ), + proxy.openConnectionReverse(localHost, utpSocketPort as Port, timer), ).rejects.toThrow(networkErrors.ErrorConnectionStartTimeout); timerStop(timer); await expect(serverConnP).resolves.toBeUndefined(); @@ -2356,17 +2347,11 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketBind = promisify(utpSocket.bind).bind(utpSocket); - await utpSocketBind(0, '127.0.0.1'); + await utpSocketBind(0, localHost); const utpSocketPort = utpSocket.address().port; - await proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - ); + await proxy.openConnectionReverse(localHost, utpSocketPort as Port); expect(proxy.getConnectionReverseCount()).toBe(1); - await proxy.closeConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - ); + await proxy.closeConnectionReverse(localHost, utpSocketPort as Port); await expect(serverConnP).resolves.toBeUndefined(); await expect(serverConnClosedP).resolves.toBeUndefined(); utpSocket.off('message', handleMessage); @@ -2414,7 +2399,7 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketBind1 = promisify(utpSocket1.bind).bind(utpSocket1); - await utpSocketBind1(0, '127.0.0.1'); + await utpSocketBind1(0, localHost); const utpSocketPort1 = utpSocket1.address().port; // Second client const utpSocket2 = UTP(); @@ -2430,25 +2415,13 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketBind2 = promisify(utpSocket2.bind).bind(utpSocket2); - await utpSocketBind2(0, '127.0.0.1'); + await utpSocketBind2(0, localHost); const utpSocketPort2 = utpSocket2.address().port; - await proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort1 as Port, - ); - await proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort2 as Port, - ); + await proxy.openConnectionReverse(localHost, utpSocketPort1 as Port); + await proxy.openConnectionReverse(localHost, utpSocketPort2 as Port); expect(proxy.getConnectionReverseCount()).toBe(2); - await proxy.closeConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort1 as Port, - ); - await proxy.closeConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort2 as Port, - ); + await proxy.closeConnectionReverse(localHost, utpSocketPort1 as Port); + await proxy.closeConnectionReverse(localHost, utpSocketPort2 as Port); expect(proxy.getConnectionReverseCount()).toBe(0); await expect(serverConnP).resolves.toBeUndefined(); await expect(serverConnClosedP).resolves.toBeUndefined(); @@ -2501,12 +2474,9 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketBind = promisify(utpSocket.bind).bind(utpSocket); - await utpSocketBind(0, '127.0.0.1'); + await utpSocketBind(0, localHost); const utpSocketPort = utpSocket.address().port; - await proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - ); + await proxy.openConnectionReverse(localHost, utpSocketPort as Port); expect(proxy.getConnectionReverseCount()).toBe(1); await expect(serverConnP).resolves.toBeUndefined(); // The server receives the end confirmation for graceful exit @@ -2569,12 +2539,9 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; const utpSocketBind = promisify(utpSocket.bind).bind(utpSocket); - await utpSocketBind(0, '127.0.0.1'); + await utpSocketBind(0, localHost); const utpSocketPort = utpSocket.address().port; - await proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - ); + await proxy.openConnectionReverse(localHost, utpSocketPort as Port); expect(proxy.getConnectionReverseCount()).toBe(1); // This retries multiple times // This will eventually fail and trigger a ErrorConnectionComposeTimeout @@ -2605,8 +2572,7 @@ describe(Proxy.name, () => { return proxy.getConnectionReverseCount(); }, (_, result) => { - if (result === 0) return true; - return false; + return result === 0; }, 100, ), @@ -2661,12 +2627,9 @@ describe(Proxy.name, () => { await utpSocketSend(data, 0, data.byteLength, externalPort, externalHost); }; const utpSocketBind = promisify(utpSocket.bind).bind(utpSocket); - await utpSocketBind(0, '127.0.0.1'); + await utpSocketBind(0, localHost); const utpSocketPort = utpSocket.address().port; - await proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - ); + await proxy.openConnectionReverse(localHost, utpSocketPort as Port); expect(proxy.getConnectionReverseCount()).toBe(1); const { p: tlsSocketClosedP, resolveP: resolveTlsSocketClosedP } = promise(); @@ -2715,8 +2678,7 @@ describe(Proxy.name, () => { return proxy.getConnectionReverseCount(); }, (_, result) => { - if (result === 0) return true; - return false; + return result === 0; }, 100, ), @@ -2746,7 +2708,7 @@ describe(Proxy.name, () => { serverHost, serverPort, } = tcpServer(); - await serverListen(0, '127.0.0.1'); + await serverListen(0, localHost); const proxy = new Proxy({ logger: logger, authToken: '', @@ -2780,12 +2742,9 @@ describe(Proxy.name, () => { const utpSocketSend = promisify(utpSocket.send).bind(utpSocket); await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; - await utpSocketBind(0, '127.0.0.1'); + await utpSocketBind(0, localHost); const utpSocketPort = utpSocket.address().port; - await proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - ); + await proxy.openConnectionReverse(localHost, utpSocketPort as Port); const utpConn = utpSocket.connect(proxyPort, proxyHost); const tlsSocket = tls.connect( { @@ -2816,10 +2775,7 @@ describe(Proxy.name, () => { await clientReadyP; await clientSecureConnectP; await serverConnP; - await proxy.closeConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - ); + await proxy.closeConnectionReverse(localHost, utpSocketPort as Port); expect(proxy.getConnectionReverseCount()).toBe(0); await clientCloseP; await serverConnEndP; @@ -2850,7 +2806,7 @@ describe(Proxy.name, () => { serverHost, serverPort, } = tcpServer(); - await serverListen(0, '127.0.0.1'); + await serverListen(0, localHost); const proxy = new Proxy({ logger: logger, authToken: '', @@ -2884,12 +2840,9 @@ describe(Proxy.name, () => { const utpSocketSend = promisify(utpSocket.send).bind(utpSocket); await utpSocketSend(data, 0, data.byteLength, proxyPort, proxyHost); }; - await utpSocketBind(0, '127.0.0.1'); + await utpSocketBind(0, localHost); const utpSocketPort = utpSocket.address().port; - await proxy.openConnectionReverse( - '127.0.0.1' as Host, - utpSocketPort as Port, - ); + await proxy.openConnectionReverse(localHost, utpSocketPort as Port); const utpConn = utpSocket.connect(proxyPort, proxyHost); const tlsSocket = tls.connect( { diff --git a/tests/network/utils.test.ts b/tests/network/utils.test.ts index 4ef705fd8..d1a26f6aa 100644 --- a/tests/network/utils.test.ts +++ b/tests/network/utils.test.ts @@ -1,6 +1,6 @@ import type { Host, Port } from '@/network/types'; - -import { utils as networkUtils, errors as networkErrors } from '@/network'; +import * as networkUtils from '@/network/utils'; +import * as networkErrors from '@/network/errors'; describe('utils', () => { test('building addresses', async () => { From e476eaf5e4dbb09f7d9d4dc2030e776df8347054 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Thu, 26 May 2022 15:00:44 +1000 Subject: [PATCH 58/74] tests: fixed write after end error in proxy tests --- tests/network/Proxy.test.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/network/Proxy.test.ts b/tests/network/Proxy.test.ts index b9a7d6e50..6d2c685eb 100644 --- a/tests/network/Proxy.test.ts +++ b/tests/network/Proxy.test.ts @@ -635,8 +635,17 @@ describe(Proxy.name, () => { let secured = false; const utpSocket = UTP.createServer(async (utpConn) => { utpConn.on('error', (e) => { + logger.warn('utpConn threw: ' + e.message); + // UTP implementation is buggy, + // we sometimes expect to see write after end error + if (e.message === 'Cannot call write after a stream was destroyed') { + return; + } utpConnError(e); }); + utpConn.on('end', async () => { + utpConn.destroy(); + }) const tlsSocket = new tls.TLSSocket(utpConn, { key: Buffer.from(serverKeyPairPem.privateKey, 'ascii'), cert: Buffer.from(serverCertPem, 'ascii'), @@ -751,8 +760,17 @@ describe(Proxy.name, () => { let secured = false; const utpSocket = UTP.createServer(async (utpConn) => { utpConn.on('error', (e) => { + logger.warn('utpConn threw: ' + e.message); + // UTP implementation is buggy, + // we sometimes expect to see write after end error + if (e.message === 'Cannot call write after a stream was destroyed') { + return; + } utpConnError(e); }); + utpConn.on('end', async () => { + utpConn.destroy(); + }) const tlsSocket = new tls.TLSSocket(utpConn, { key: Buffer.from(serverKeyPairPem.privateKey, 'ascii'), cert: Buffer.from(serverCertPem, 'ascii'), @@ -874,8 +892,17 @@ describe(Proxy.name, () => { // This UTP server will hold the connection const utpSocket = UTP.createServer(async (utpConn) => { utpConn.on('error', (e) => { + logger.warn('utpConn threw: ' + e.message); + // UTP implementation is buggy, + // we sometimes expect to see write after end error + if (e.message === 'Cannot call write after a stream was destroyed') { + return; + } utpConnError(e); }); + utpConn.on('end', async () => { + utpConn.destroy(); + }) const tlsSocket = new tls.TLSSocket(utpConn, { key: Buffer.from(serverKeyPairPem.privateKey, 'ascii'), cert: Buffer.from(serverCertPem, 'ascii'), @@ -1150,8 +1177,17 @@ describe(Proxy.name, () => { // This UTP server will hold the connection const utpSocket = UTP.createServer(async (utpConn) => { utpConn.on('error', (e) => { + logger.warn('utpConn threw: ' + e.message); + // UTP implementation is buggy, + // we sometimes expect to see write after end error + if (e.message === 'Cannot call write after a stream was destroyed') { + return; + } utpConnError(e); }); + utpConn.on('end', async () => { + utpConn.destroy(); + }) const tlsSocket = new tls.TLSSocket(utpConn, { key: Buffer.from(serverKeyPairPem.privateKey, 'ascii'), cert: Buffer.from(serverCertPem, 'ascii'), From b69e544ed4b3e53afe1ed6967d76988efad5c8b3 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Thu, 26 May 2022 15:48:38 +1000 Subject: [PATCH 59/74] tests: fixed odd internal error for one test It was just a problem with trying to connect to '0.0.0.0' with the UTP socket. --- tests/network/Proxy.test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/network/Proxy.test.ts b/tests/network/Proxy.test.ts index 6d2c685eb..024425ff8 100644 --- a/tests/network/Proxy.test.ts +++ b/tests/network/Proxy.test.ts @@ -645,7 +645,7 @@ describe(Proxy.name, () => { }); utpConn.on('end', async () => { utpConn.destroy(); - }) + }); const tlsSocket = new tls.TLSSocket(utpConn, { key: Buffer.from(serverKeyPairPem.privateKey, 'ascii'), cert: Buffer.from(serverCertPem, 'ascii'), @@ -770,7 +770,7 @@ describe(Proxy.name, () => { }); utpConn.on('end', async () => { utpConn.destroy(); - }) + }); const tlsSocket = new tls.TLSSocket(utpConn, { key: Buffer.from(serverKeyPairPem.privateKey, 'ascii'), cert: Buffer.from(serverCertPem, 'ascii'), @@ -902,7 +902,7 @@ describe(Proxy.name, () => { }); utpConn.on('end', async () => { utpConn.destroy(); - }) + }); const tlsSocket = new tls.TLSSocket(utpConn, { key: Buffer.from(serverKeyPairPem.privateKey, 'ascii'), cert: Buffer.from(serverCertPem, 'ascii'), @@ -1187,7 +1187,7 @@ describe(Proxy.name, () => { }); utpConn.on('end', async () => { utpConn.destroy(); - }) + }); const tlsSocket = new tls.TLSSocket(utpConn, { key: Buffer.from(serverKeyPairPem.privateKey, 'ascii'), cert: Buffer.from(serverCertPem, 'ascii'), @@ -2554,7 +2554,8 @@ describe(Proxy.name, () => { await proxy.start({ serverHost: serverHost(), serverPort: serverPort(), - + forwardHost: localHost, + proxyHost: localHost, tlsConfig: { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, From 3f853b4618c50580fbc7ec01429198f4806c1f55 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Thu, 26 May 2022 16:14:53 +1000 Subject: [PATCH 60/74] syntax: general clean up proxy tests --- tests/network/Proxy.test.ts | 56 +++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/tests/network/Proxy.test.ts b/tests/network/Proxy.test.ts index 024425ff8..f199f7a0b 100644 --- a/tests/network/Proxy.test.ts +++ b/tests/network/Proxy.test.ts @@ -11,7 +11,7 @@ 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 { promisify, promise, timerStart, timerStop, poll } from '@/utils'; +import { poll, promise, promisify, timerStart, timerStop } from '@/utils'; import * as testUtils from '../utils'; /** @@ -141,6 +141,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -157,6 +159,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -170,6 +174,7 @@ describe(Proxy.name, () => { // Start it again await proxy.start({ forwardHost: '::1' as Host, + proxyHost: localHost, serverHost: localHost, serverPort: port, tlsConfig: { @@ -193,6 +198,7 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, serverHost: localHost, serverPort: port, }); @@ -244,6 +250,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -278,6 +286,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -336,6 +346,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -395,6 +407,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -501,6 +515,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -619,6 +635,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -744,6 +762,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -875,6 +895,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -1011,6 +1033,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -1160,6 +1184,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -1318,6 +1344,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -1489,6 +1517,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -1645,6 +1675,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -1777,6 +1809,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -1895,6 +1929,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -2033,6 +2069,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -2140,6 +2178,8 @@ describe(Proxy.name, () => { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, }, + proxyHost: localHost, + forwardHost: localHost, serverHost: localHost, serverPort: port, }); @@ -2291,7 +2331,8 @@ describe(Proxy.name, () => { await proxy.start({ serverHost: serverHost(), serverPort: serverPort(), - + proxyHost: localHost, + forwardHost: localHost, tlsConfig: { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, @@ -2322,7 +2363,8 @@ describe(Proxy.name, () => { await proxy.start({ serverHost: serverHost(), serverPort: serverPort(), - + proxyHost: localHost, + forwardHost: localHost, tlsConfig: { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, @@ -2362,6 +2404,8 @@ describe(Proxy.name, () => { await proxy.start({ serverHost: serverHost(), serverPort: serverPort(), + proxyHost: localHost, + forwardHost: localHost, tlsConfig: { keyPrivatePem: keyPairPem.privateKey, @@ -2413,6 +2457,8 @@ describe(Proxy.name, () => { await proxy.start({ serverHost: serverHost(), serverPort: serverPort(), + proxyHost: localHost, + forwardHost: localHost, tlsConfig: { keyPrivatePem: keyPairPem.privateKey, @@ -2489,6 +2535,8 @@ describe(Proxy.name, () => { await proxy.start({ serverHost: serverHost(), serverPort: serverPort(), + proxyHost: localHost, + forwardHost: localHost, tlsConfig: { keyPrivatePem: keyPairPem.privateKey, @@ -2648,6 +2696,7 @@ describe(Proxy.name, () => { certChainPem: certPem, }, proxyHost: localHost, + forwardHost: localHost, }); const externalHost = proxy.getProxyHost(); const externalPort = proxy.getProxyPort(); @@ -2754,6 +2803,7 @@ describe(Proxy.name, () => { serverHost: serverHost(), serverPort: serverPort(), proxyHost: localHost, + forwardHost: localHost, tlsConfig: { keyPrivatePem: keyPairPem.privateKey, certChainPem: certPem, From 314eb1cb5cd99b281d62dd1e6594cc1fa51a778b Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 31 May 2022 14:58:57 +1000 Subject: [PATCH 61/74] build: updated `@matrixai/db` and `encryptedfs` dependencies --- package-lock.json | 62 ++++++++++++----------------------------------- package.json | 4 +-- 2 files changed, 18 insertions(+), 48 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02a32f2c0..8e1b8194b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@grpc/grpc-js": "1.6.7", "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.4", - "@matrixai/db": "^4.0.1", + "@matrixai/db": "^4.0.2", "@matrixai/errors": "^1.1.1", "@matrixai/id": "^3.3.3", "@matrixai/logger": "^2.1.1", @@ -25,7 +25,7 @@ "commander": "^8.3.0", "cross-fetch": "^3.0.6", "cross-spawn": "^7.0.3", - "encryptedfs": "^3.5.1", + "encryptedfs": "^3.5.2", "fast-fuzzy": "^1.10.8", "fd-lock": "^1.2.0", "google-protobuf": "^3.14.0", @@ -2565,9 +2565,9 @@ } }, "node_modules/@matrixai/db": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.1.tgz", - "integrity": "sha512-pgW0LXdMqx7daOxByP9Y1T0BGOi4wC8oME4wS21nOVOYV/Ht3Zf0ogfkfzaB/nD4m7x90TamwMK8TeUI5mxdaw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.2.tgz", + "integrity": "sha512-09gRmxATT65oDRXvbAYRg2AVrBUcQGXWkrhA0dmmPH9QE4O7CG1pLxu0mOd8QinUhpe18wJR9IrymSmzdgYUUg==", "dependencies": { "@matrixai/async-init": "^1.7.3", "@matrixai/errors": "^1.1.1", @@ -4601,13 +4601,13 @@ } }, "node_modules/encryptedfs": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.1.tgz", - "integrity": "sha512-gGyL8Ax61WAte3ABiz26WuFSIhEmTh0KcGfugkQunpdcEKoex/3T+2l6InCv35VSFAQ/l5vbBFAYFdKT15JL2w==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.2.tgz", + "integrity": "sha512-VAskWgjozncNztQZtKRHedK7DDQ7DwLEQ1a/EGZfSCsX/ardcJg54pVwwyz/KP5At1zPJUB0iboqoMk8/m09xw==", "dependencies": { "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.4", - "@matrixai/db": "3.3.3", + "@matrixai/db": "^4.0.2", "@matrixai/errors": "^1.1.1", "@matrixai/logger": "^2.1.1", "@matrixai/resources": "^1.1.3", @@ -4621,21 +4621,6 @@ "util-callbackify": "^1.0.0" } }, - "node_modules/encryptedfs/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/encryptedfs/node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -13517,9 +13502,9 @@ } }, "@matrixai/db": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.1.tgz", - "integrity": "sha512-pgW0LXdMqx7daOxByP9Y1T0BGOi4wC8oME4wS21nOVOYV/Ht3Zf0ogfkfzaB/nD4m7x90TamwMK8TeUI5mxdaw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.2.tgz", + "integrity": "sha512-09gRmxATT65oDRXvbAYRg2AVrBUcQGXWkrhA0dmmPH9QE4O7CG1pLxu0mOd8QinUhpe18wJR9IrymSmzdgYUUg==", "requires": { "@matrixai/async-init": "^1.7.3", "@matrixai/errors": "^1.1.1", @@ -15107,13 +15092,13 @@ } }, "encryptedfs": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.1.tgz", - "integrity": "sha512-gGyL8Ax61WAte3ABiz26WuFSIhEmTh0KcGfugkQunpdcEKoex/3T+2l6InCv35VSFAQ/l5vbBFAYFdKT15JL2w==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.2.tgz", + "integrity": "sha512-VAskWgjozncNztQZtKRHedK7DDQ7DwLEQ1a/EGZfSCsX/ardcJg54pVwwyz/KP5At1zPJUB0iboqoMk8/m09xw==", "requires": { "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.4", - "@matrixai/db": "3.3.3", + "@matrixai/db": "^4.0.2", "@matrixai/errors": "^1.1.1", "@matrixai/logger": "^2.1.1", "@matrixai/resources": "^1.1.3", @@ -15127,21 +15112,6 @@ "util-callbackify": "^1.0.0" }, "dependencies": { - "@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==", - "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", - "threads": "^1.6.5" - } - }, "node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", diff --git a/package.json b/package.json index 203eb5b7e..57057a423 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@grpc/grpc-js": "1.6.7", "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.4", - "@matrixai/db": "^4.0.1", + "@matrixai/db": "^4.0.2", "@matrixai/errors": "^1.1.1", "@matrixai/id": "^3.3.3", "@matrixai/logger": "^2.1.1", @@ -89,7 +89,7 @@ "commander": "^8.3.0", "cross-fetch": "^3.0.6", "cross-spawn": "^7.0.3", - "encryptedfs": "^3.5.1", + "encryptedfs": "^3.5.2", "fast-fuzzy": "^1.10.8", "fd-lock": "^1.2.0", "google-protobuf": "^3.14.0", From 897895fa4776ea566cee6619525747bdbb88c86b Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Tue, 31 May 2022 16:18:36 +1000 Subject: [PATCH 62/74] fix: updated usage of iterators to use `valueAsBuff: false` option --- src/acl/ACL.ts | 9 ++++----- src/discovery/Discovery.ts | 13 +++++++------ src/gestalts/GestaltGraph.ts | 9 ++++----- src/nodes/NodeGraph.ts | 9 ++++----- src/notifications/NotificationsManager.ts | 13 +++++++------ src/sigchain/Sigchain.ts | 17 +++++++++-------- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/acl/ACL.ts b/src/acl/ACL.ts index caa308f13..ac83ade13 100644 --- a/src/acl/ACL.ts +++ b/src/acl/ACL.ts @@ -16,7 +16,6 @@ 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'; @@ -176,12 +175,12 @@ class ACL { return this.withTransactionF(async (tran) => this.getVaultPerms(tran)); } const vaultPerms: Record> = {}; - for await (const [keyPath, value] of tran.iterator(undefined, [ - ...this.aclVaultsDbPath, - ])) { + for await (const [keyPath, nodeIds] of tran.iterator>( + { valueAsBuffer: false }, + [...this.aclVaultsDbPath], + )) { const key = keyPath[0] as Buffer; const vaultId = IdInternal.fromBuffer(key); - const nodeIds = dbUtils.deserialize>(value); const nodePerm: Record = {}; const nodeIdsGc: Set = new Set(); for (const nodeIdString in nodeIds) { diff --git a/src/discovery/Discovery.ts b/src/discovery/Discovery.ts index 576ecf29f..3e4f9d7d0 100644 --- a/src/discovery/Discovery.ts +++ b/src/discovery/Discovery.ts @@ -26,7 +26,6 @@ import { 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'; @@ -203,13 +202,12 @@ class Discovery { // Processing queue this.logger.debug('DiscoveryQueue is processing'); - for await (const [keyPath, value] of this.db.iterator( - {}, + for await (const [keyPath, vertex] of this.db.iterator( + { valueAsBuffer: false }, this.discoveryQueueDbPath, )) { const key = keyPath[0] as Buffer; const vertexId = IdInternal.fromBuffer(key); - const vertex = dbUtils.deserialize(value); this.logger.debug(`Processing vertex: ${vertex}`); const vertexGId = gestaltsUtils.ungestaltKey(vertex); switch (vertexGId.type) { @@ -448,9 +446,12 @@ class Discovery { await resources.withF( [this.db.transaction(), this.lock.lock()], async ([tran]) => { - const valueIterator = tran.iterator({}, this.discoveryQueueDbPath); + const valueIterator = tran.iterator( + { valueAsBuffer: false }, + this.discoveryQueueDbPath, + ); for await (const [, value] of valueIterator) { - if (value.toString() === gestaltKey) { + if (value === gestaltKey) { return; } } diff --git a/src/gestalts/GestaltGraph.ts b/src/gestalts/GestaltGraph.ts index 0cb613a31..b746700d9 100644 --- a/src/gestalts/GestaltGraph.ts +++ b/src/gestalts/GestaltGraph.ts @@ -17,7 +17,6 @@ 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'; @@ -104,11 +103,11 @@ class GestaltGraph { return this.withTransactionF(async (tran) => this.getGestalts(tran)); } const unvisited: Map = new Map(); - for await (const [k, v] of tran.iterator(undefined, [ - ...this.gestaltGraphMatrixDbPath, - ])) { + for await (const [k, gKs] of tran.iterator( + { valueAsBuffer: false }, + [...this.gestaltGraphMatrixDbPath], + )) { const gK = k.toString() as GestaltKey; - const gKs = dbUtils.deserialize(v); unvisited.set(gK, gKs); } const gestalts: Array = []; diff --git a/src/nodes/NodeGraph.ts b/src/nodes/NodeGraph.ts index 31cc5d130..4d623dbce 100644 --- a/src/nodes/NodeGraph.ts +++ b/src/nodes/NodeGraph.ts @@ -2,7 +2,6 @@ import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db'; import type { NodeAddress, NodeBucket, NodeId } from './types'; import type KeyManager from '../keys/KeyManager'; import type { Host, Hostname, Port } from '../network/types'; -import { utils as dbUtils } from '@matrixai/db'; import lexi from 'lexicographic-integer'; import Logger from '@matrixai/logger'; import { @@ -309,10 +308,10 @@ class NodeGraph { 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); + for await (const [, bucket] of tran.iterator( + { keys: false, valueAsBuffer: false }, + [...this.nodeGraphBucketsDbPath], + )) { buckets.push(bucket); } return buckets; diff --git a/src/notifications/NotificationsManager.ts b/src/notifications/NotificationsManager.ts index 58b6fc42c..8031311bf 100644 --- a/src/notifications/NotificationsManager.ts +++ b/src/notifications/NotificationsManager.ts @@ -367,11 +367,13 @@ class NotificationsManager { tran: DBTransaction, ): Promise> { const notificationIds: Array = []; - const messageIterator = tran.iterator({}, this.notificationsMessagesDbPath); - for await (const [keyPath, value] of messageIterator) { + const messageIterator = tran.iterator( + { valueAsBuffer: false }, + this.notificationsMessagesDbPath, + ); + for await (const [keyPath, notification] of messageIterator) { const key = keyPath[0] as Buffer; const notificationId = IdInternal.fromBuffer(key); - const notification = JSON.parse(value.toString()) as Notification; if (type === 'all') { notificationIds.push(notificationId); } else if (type === 'unread') { @@ -388,11 +390,10 @@ class NotificationsManager { tran: DBTransaction, ): Promise> { const notifications: Array = []; - for await (const [, value] of tran.iterator( - {}, + for await (const [, notification] of tran.iterator( + { valueAsBuffer: false }, this.notificationsMessagesDbPath, )) { - const notification = JSON.parse(value.toString()) as Notification; if (type === 'all') { notifications.push(notification); } else if (type === 'unread') { diff --git a/src/sigchain/Sigchain.ts b/src/sigchain/Sigchain.ts index a2a1f0af4..da543b82b 100644 --- a/src/sigchain/Sigchain.ts +++ b/src/sigchain/Sigchain.ts @@ -10,7 +10,6 @@ import type { } from '../claims/types'; import type KeyManager from '../keys/KeyManager'; import type { NodeIdEncoded } from '../nodes/types'; -import { utils as dbUtils } from '@matrixai/db'; import Logger from '@matrixai/logger'; import { IdInternal } from '@matrixai/id'; import { @@ -287,12 +286,13 @@ class Sigchain { return this.withTransactionF(async (tran) => this.getChainData(tran)); } const chainData: ChainDataEncoded = {}; - const readIterator = tran.iterator({}, [...this.sigchainClaimsDbPath]); - for await (const [keyPath, value] of readIterator) { + const readIterator = tran.iterator({ valueAsBuffer: false }, [ + ...this.sigchainClaimsDbPath, + ]); + for await (const [keyPath, claimEncoded] of readIterator) { const key = keyPath[0] as Buffer; const claimId = IdInternal.fromBuffer(key); - chainData[claimsUtils.encodeClaimId(claimId)] = - dbUtils.deserialize(value); + chainData[claimsUtils.encodeClaimId(claimId)] = claimEncoded; } return chainData; } @@ -316,9 +316,10 @@ class Sigchain { ); } const relevantClaims: Array = []; - const readIterator = tran.iterator({}, [...this.sigchainClaimsDbPath]); - for await (const [, value] of readIterator) { - const claim = dbUtils.deserialize(value); + const readIterator = tran.iterator({ valueAsBuffer: false }, [ + ...this.sigchainClaimsDbPath, + ]); + for await (const [, claim] of readIterator) { const decodedClaim = claimsUtils.decodeClaim(claim); if (decodedClaim.payload.data.type === claimType) { relevantClaims.push(claim); From 45cb2d999e56b702d411a178b6334120155a507a Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 1 Jun 2022 11:56:17 +1000 Subject: [PATCH 63/74] fix: importing `LockRequest` for `VaultManager` --- package-lock.json | 14 +++++++------- package.json | 2 +- src/vaults/VaultManager.ts | 11 ++--------- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8e1b8194b..397dad844 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@grpc/grpc-js": "1.6.7", "@matrixai/async-init": "^1.7.3", - "@matrixai/async-locks": "^2.2.4", + "@matrixai/async-locks": "^2.2.5", "@matrixai/db": "^4.0.2", "@matrixai/errors": "^1.1.1", "@matrixai/id": "^3.3.3", @@ -2555,9 +2555,9 @@ } }, "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==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.2.5.tgz", + "integrity": "sha512-Yokd3p64FciLNSW04Qox+UHJulxnWQIhHt3h9sMmgoiTsyZcOgeYfPAJrtZiRnhaUXhfBczPy4VPP2e5lrXgig==", "dependencies": { "@matrixai/errors": "^1.1.1", "@matrixai/resources": "^1.1.3", @@ -13492,9 +13492,9 @@ } }, "@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==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@matrixai/async-locks/-/async-locks-2.2.5.tgz", + "integrity": "sha512-Yokd3p64FciLNSW04Qox+UHJulxnWQIhHt3h9sMmgoiTsyZcOgeYfPAJrtZiRnhaUXhfBczPy4VPP2e5lrXgig==", "requires": { "@matrixai/errors": "^1.1.1", "@matrixai/resources": "^1.1.3", diff --git a/package.json b/package.json index 57057a423..f0a91ed8a 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "dependencies": { "@grpc/grpc-js": "1.6.7", "@matrixai/async-init": "^1.7.3", - "@matrixai/async-locks": "^2.2.4", + "@matrixai/async-locks": "^2.2.5", "@matrixai/db": "^4.0.2", "@matrixai/errors": "^1.1.1", "@matrixai/id": "^3.3.3", diff --git a/src/vaults/VaultManager.ts b/src/vaults/VaultManager.ts index ecf795a7f..fb09137a0 100644 --- a/src/vaults/VaultManager.ts +++ b/src/vaults/VaultManager.ts @@ -7,7 +7,7 @@ import type { VaultIdEncoded, } from './types'; import type { Vault } from './Vault'; -import type { FileSystem, ToString } from '../types'; +import type { FileSystem } from '../types'; import type { PolykeyWorkerManagerInterface } from '../workers/types'; import type { NodeId } from '../nodes/types'; import type KeyManager from '../keys/KeyManager'; @@ -17,7 +17,7 @@ import type NotificationsManager from '../notifications/NotificationsManager'; import type ACL from '../acl/ACL'; import type { RemoteInfo } from './VaultInternal'; import type { VaultAction } from './types'; -import type { Lockable } from '@matrixai/async-locks'; +import type { LockRequest } from '@matrixai/async-locks'; import path from 'path'; import { PassThrough } from 'readable-stream'; import { EncryptedFS, errors as encryptedFsErrors } from 'encryptedfs'; @@ -52,13 +52,6 @@ type VaultMetadata = { remoteInfo?: RemoteInfo; }; -// FIXME, this is a HACK since this type isn't exported -type LockRequest = [ - key: ToString, - lockConstructor: new () => L, - ...lockingParams: Parameters, -]; - interface VaultManager extends CreateDestroyStartStop {} @CreateDestroyStartStop( new vaultsErrors.ErrorVaultManagerRunning(), From 51b0f1de460c9a85e4ac3c7fca64f225646cb4c4 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 1 Jun 2022 12:34:06 +1000 Subject: [PATCH 64/74] fix: bug with `decryptWithKey` utility --- src/keys/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keys/utils.ts b/src/keys/utils.ts index 02ea313f9..e36849f47 100644 --- a/src/keys/utils.ts +++ b/src/keys/utils.ts @@ -541,7 +541,7 @@ async function decryptWithKey( cipherText: ArrayBuffer, ): Promise { const cipherTextBuf = Buffer.from(cipherText); - if (cipherTextBuf.byteLength <= 32) { + if (cipherTextBuf.byteLength < 32) { return; } const iv = cipherTextBuf.subarray(0, ivSize); From 8b284730647f93712a666557ce8ac8eaa76710de Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 1 Jun 2022 14:08:28 +1000 Subject: [PATCH 65/74] build: Updated `encryptedfs` and `@matrixai/db` version --- package-lock.json | 28 ++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 397dad844..e90839fdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@grpc/grpc-js": "1.6.7", "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.5", - "@matrixai/db": "^4.0.2", + "@matrixai/db": "^4.0.5", "@matrixai/errors": "^1.1.1", "@matrixai/id": "^3.3.3", "@matrixai/logger": "^2.1.1", @@ -25,7 +25,7 @@ "commander": "^8.3.0", "cross-fetch": "^3.0.6", "cross-spawn": "^7.0.3", - "encryptedfs": "^3.5.2", + "encryptedfs": "^3.5.3", "fast-fuzzy": "^1.10.8", "fd-lock": "^1.2.0", "google-protobuf": "^3.14.0", @@ -2565,9 +2565,9 @@ } }, "node_modules/@matrixai/db": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.2.tgz", - "integrity": "sha512-09gRmxATT65oDRXvbAYRg2AVrBUcQGXWkrhA0dmmPH9QE4O7CG1pLxu0mOd8QinUhpe18wJR9IrymSmzdgYUUg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.5.tgz", + "integrity": "sha512-X3gBcyPxC+bTEfi1J1Y49n1bglvg7HjM8MKNH5s+OUEswqKSZgeg1uWfXqvUqq72yjBtgRi4Ghmy4MdrIB1oMw==", "dependencies": { "@matrixai/async-init": "^1.7.3", "@matrixai/errors": "^1.1.1", @@ -4601,9 +4601,9 @@ } }, "node_modules/encryptedfs": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.2.tgz", - "integrity": "sha512-VAskWgjozncNztQZtKRHedK7DDQ7DwLEQ1a/EGZfSCsX/ardcJg54pVwwyz/KP5At1zPJUB0iboqoMk8/m09xw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.3.tgz", + "integrity": "sha512-2cTz6/8lUF2WFv6YNA9RwSASBh6bHIJqCbOWFr1RCo/vEHeR1+OKK0F+Xu4ujBlLsz3/a6NwT6/UoHl8Zn5rCg==", "dependencies": { "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.4", @@ -13502,9 +13502,9 @@ } }, "@matrixai/db": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.2.tgz", - "integrity": "sha512-09gRmxATT65oDRXvbAYRg2AVrBUcQGXWkrhA0dmmPH9QE4O7CG1pLxu0mOd8QinUhpe18wJR9IrymSmzdgYUUg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@matrixai/db/-/db-4.0.5.tgz", + "integrity": "sha512-X3gBcyPxC+bTEfi1J1Y49n1bglvg7HjM8MKNH5s+OUEswqKSZgeg1uWfXqvUqq72yjBtgRi4Ghmy4MdrIB1oMw==", "requires": { "@matrixai/async-init": "^1.7.3", "@matrixai/errors": "^1.1.1", @@ -15092,9 +15092,9 @@ } }, "encryptedfs": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.2.tgz", - "integrity": "sha512-VAskWgjozncNztQZtKRHedK7DDQ7DwLEQ1a/EGZfSCsX/ardcJg54pVwwyz/KP5At1zPJUB0iboqoMk8/m09xw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/encryptedfs/-/encryptedfs-3.5.3.tgz", + "integrity": "sha512-2cTz6/8lUF2WFv6YNA9RwSASBh6bHIJqCbOWFr1RCo/vEHeR1+OKK0F+Xu4ujBlLsz3/a6NwT6/UoHl8Zn5rCg==", "requires": { "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.4", diff --git a/package.json b/package.json index f0a91ed8a..fc6ba19ca 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@grpc/grpc-js": "1.6.7", "@matrixai/async-init": "^1.7.3", "@matrixai/async-locks": "^2.2.5", - "@matrixai/db": "^4.0.2", + "@matrixai/db": "^4.0.5", "@matrixai/errors": "^1.1.1", "@matrixai/id": "^3.3.3", "@matrixai/logger": "^2.1.1", @@ -89,7 +89,7 @@ "commander": "^8.3.0", "cross-fetch": "^3.0.6", "cross-spawn": "^7.0.3", - "encryptedfs": "^3.5.2", + "encryptedfs": "^3.5.3", "fast-fuzzy": "^1.10.8", "fd-lock": "^1.2.0", "google-protobuf": "^3.14.0", From bfc1a9216ab4dcc507c8deb3ac9e3ead5fd2bac7 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Wed, 1 Jun 2022 15:16:45 +1000 Subject: [PATCH 66/74] refactor: moving `ClientMetadata` to GRPC domain Having `ClientMetadata` in the top-level types caused an import loop. By moving it and `ErrorPolykeyRemote` to the grpc domain this loop is resolved. This was the best option since now all usage of `ClientMetadata` is inside the grpc domain. --- src/bin/utils/utils.ts | 11 ++-- src/errors.ts | 55 ------------------- src/grpc/errors.ts | 55 +++++++++++++++++++ src/grpc/types.ts | 11 ++++ src/grpc/utils/utils.ts | 5 +- src/types.ts | 10 ---- .../agent/service/nodesCrossSignClaim.test.ts | 10 +++- tests/bin/utils.test.ts | 13 +++-- tests/grpc/utils.test.ts | 16 +++--- tests/utils.ts | 4 +- 10 files changed, 99 insertions(+), 91 deletions(-) diff --git a/src/bin/utils/utils.ts b/src/bin/utils/utils.ts index 0e66b8e23..51b259dfb 100644 --- a/src/bin/utils/utils.ts +++ b/src/bin/utils/utils.ts @@ -4,10 +4,11 @@ import { LogLevel } from '@matrixai/logger'; import * as grpc from '@grpc/grpc-js'; import { AbstractError } from '@matrixai/errors'; import * as binProcessors from './processors'; +import ErrorPolykey from '../../ErrorPolykey'; import * as binErrors from '../errors'; import * as clientUtils from '../../client/utils'; import * as clientErrors from '../../client/errors'; -import * as errors from '../../errors'; +import * as grpcErrors from '../../grpc/errors'; import * as nodesUtils from '../../nodes/utils'; import * as utils from '../../utils'; @@ -105,7 +106,7 @@ function outputFormatter(msg: OutputObject): string { let currError = msg.data; let indent = ' '; while (currError != null) { - if (currError instanceof errors.ErrorPolykeyRemote) { + if (currError instanceof grpcErrors.ErrorPolykeyRemote) { output += `${currError.name}: ${currError.description}`; if (currError.message && currError.message !== '') { output += ` - ${currError.message}`; @@ -120,7 +121,7 @@ function outputFormatter(msg: OutputObject): string { output += `${indent}timestamp\t${currError.timestamp}\n`; output += `${indent}remote error: `; currError = currError.cause; - } else if (currError instanceof errors.ErrorPolykey) { + } else if (currError instanceof ErrorPolykey) { output += `${currError.name}: ${currError.description}`; if (currError.message && currError.message !== '') { output += ` - ${currError.message}`; @@ -133,7 +134,7 @@ function outputFormatter(msg: OutputObject): string { } if (currError.cause) { output += `${indent}cause: `; - if (currError.cause instanceof errors.ErrorPolykey) { + if (currError.cause instanceof ErrorPolykey) { currError = currError.cause; } else if (currError.cause instanceof Error) { output += `${currError.cause.name}`; @@ -214,7 +215,7 @@ async function retryAuthentication( function remoteErrorCause(e: any): [any, number] { let errorCause = e; let depth = 0; - while (errorCause instanceof errors.ErrorPolykeyRemote) { + while (errorCause instanceof grpcErrors.ErrorPolykeyRemote) { errorCause = errorCause.cause; depth++; } diff --git a/src/errors.ts b/src/errors.ts index 12af747ab..3f6aba171 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,59 +1,5 @@ -import type { Class } from '@matrixai/errors'; -import type { ClientMetadata } from './types'; import ErrorPolykey from './ErrorPolykey'; import sysexits from './utils/sysexits'; -import * as nodesUtils from './nodes/utils'; - -class ErrorPolykeyRemote extends ErrorPolykey { - static description = 'Remote error from RPC call'; - exitCode = sysexits.UNAVAILABLE; - metadata: ClientMetadata; - - constructor(metadata: ClientMetadata, message?: string, options?) { - super(message, options); - this.metadata = metadata; - } - - 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.metadata !== 'object' || - 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 parsedMetadata: ClientMetadata = { - ...json.data.metadata, - nodeId: nodesUtils.decodeNodeId(json.data.metadata.nodeId), - }; - const e = new this(parsedMetadata, 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.metadata = { - ...this.metadata, - nodeId: nodesUtils.encodeNodeId(this.metadata.nodeId), - }; - return json; - } -} class ErrorPolykeyUnimplemented extends ErrorPolykey { static description = 'This is an unimplemented functionality'; @@ -104,7 +50,6 @@ export { ErrorPolykey, ErrorPolykeyUnimplemented, ErrorPolykeyUnknown, - ErrorPolykeyRemote, ErrorPolykeyAgentRunning, ErrorPolykeyAgentNotRunning, ErrorPolykeyAgentDestroyed, diff --git a/src/grpc/errors.ts b/src/grpc/errors.ts index 023dffdc3..aed2281c2 100644 --- a/src/grpc/errors.ts +++ b/src/grpc/errors.ts @@ -1,4 +1,7 @@ +import type { Class } from '@matrixai/errors'; +import type { ClientMetadata } from './types'; import { ErrorPolykey, sysexits } from '../errors'; +import * as nodesUtils from '../nodes/utils'; class ErrorGRPC extends ErrorPolykey {} @@ -47,6 +50,57 @@ class ErrorGRPCServerVerification extends ErrorGRPC { exitCode = sysexits.UNAVAILABLE; } +class ErrorPolykeyRemote extends ErrorPolykey { + static description = 'Remote error from RPC call'; + exitCode = sysexits.UNAVAILABLE; + metadata: ClientMetadata; + + constructor(metadata: ClientMetadata, message?: string, options?) { + super(message, options); + this.metadata = metadata; + } + + 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.metadata !== 'object' || + 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 parsedMetadata: ClientMetadata = { + ...json.data.metadata, + nodeId: nodesUtils.decodeNodeId(json.data.metadata.nodeId), + }; + const e = new this(parsedMetadata, 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.metadata = { + ...this.metadata, + nodeId: nodesUtils.encodeNodeId(this.metadata.nodeId), + }; + return json; + } +} + export { ErrorGRPC, ErrorGRPCClientTimeout, @@ -58,4 +112,5 @@ export { ErrorGRPCServerShutdown, ErrorGRPCServerNotSecured, ErrorGRPCServerVerification, + ErrorPolykeyRemote, }; diff --git a/src/grpc/types.ts b/src/grpc/types.ts index 41061c3dd..8f600c2ce 100644 --- a/src/grpc/types.ts +++ b/src/grpc/types.ts @@ -8,6 +8,9 @@ import type { UntypedServiceImplementation, Metadata, } from '@grpc/grpc-js'; +import type { NodeId } from '../nodes/types'; +import type { Host, Port } from '../network/types'; +import type { POJO } from '../types'; type Services = Array< [ @@ -100,6 +103,13 @@ interface AsyncGeneratorDuplexStreamClient< meta: Promise; } +type ClientMetadata = { + nodeId: NodeId; + host: Host; + port: Port; + command: string; +} & POJO; + export type { Services, PromiseUnaryCall, @@ -109,4 +119,5 @@ export type { AsyncGeneratorWritableStreamClient, AsyncGeneratorDuplexStream, AsyncGeneratorDuplexStreamClient, + ClientMetadata, }; diff --git a/src/grpc/utils/utils.ts b/src/grpc/utils/utils.ts index 1b98d310f..f696f37a2 100644 --- a/src/grpc/utils/utils.ts +++ b/src/grpc/utils/utils.ts @@ -28,7 +28,8 @@ import type { AsyncGeneratorDuplexStreamClient, } from '../types'; import type { CertificatePemChain, PrivateKeyPem } from '../../keys/types'; -import type { POJO, ClientMetadata } from '../../types'; +import type { POJO } from '../../types'; +import type { ClientMetadata } from '../types'; import type { NodeId } from '../../nodes/types'; import { Buffer } from 'buffer'; import { AbstractError } from '@matrixai/errors'; @@ -199,7 +200,7 @@ function toError( if (isNaN(parseInt(key)) && e.code === grpc.status[key]) { if (key === 'UNKNOWN' && errorData != null) { const error: Error = JSON.parse(errorData, reviver); - const remoteError = new errors.ErrorPolykeyRemote( + const remoteError = new grpcErrors.ErrorPolykeyRemote( metadata, error.message, { diff --git a/src/types.ts b/src/types.ts index 0e41f366f..8fba1fc08 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,7 +1,5 @@ // eslint-disable-next-line no-restricted-imports -- Interim types for FileSystem import type fs from 'fs'; -import type { Host, Port } from './network/types'; -import type { NodeId } from './nodes/types'; /** * Plain data dictionary @@ -79,13 +77,6 @@ interface FileSystem { type FileHandle = fs.promises.FileHandle; -type ClientMetadata = { - nodeId: NodeId; - host: Host; - port: Port; - command: string; -} & POJO; - export type { POJO, Opaque, @@ -98,5 +89,4 @@ export type { Timer, FileSystem, FileHandle, - ClientMetadata, }; diff --git a/tests/agent/service/nodesCrossSignClaim.test.ts b/tests/agent/service/nodesCrossSignClaim.test.ts index bc676db86..aea5d7a6e 100644 --- a/tests/agent/service/nodesCrossSignClaim.test.ts +++ b/tests/agent/service/nodesCrossSignClaim.test.ts @@ -5,7 +5,6 @@ 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'; @@ -15,6 +14,7 @@ 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 grpcErrors from '@/grpc/errors'; import * as testNodesUtils from '../../nodes/utils'; import * as testUtils from '../../utils'; @@ -203,7 +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(ErrorPolykeyRemote); + await expect(() => genClaims.read()).rejects.toThrow( + grpcErrors.ErrorPolykeyRemote, + ); expect(genClaims.stream.destroyed).toBe(true); // Check sigchain's lock is released // Revert side effects @@ -222,7 +224,9 @@ describe('nodesCrossSignClaim', () => { intermediaryNoSignature, ); await genClaims.write(crossSignMessageUndefinedSinglySignature); - await expect(() => genClaims.read()).rejects.toThrow(ErrorPolykeyRemote); + await expect(() => genClaims.read()).rejects.toThrow( + grpcErrors.ErrorPolykeyRemote, + ); expect(genClaims.stream.destroyed).toBe(true); // Check sigchain's lock is released // Revert side effects diff --git a/tests/bin/utils.test.ts b/tests/bin/utils.test.ts index 45e6bd870..80b9aa3bf 100644 --- a/tests/bin/utils.test.ts +++ b/tests/bin/utils.test.ts @@ -1,7 +1,8 @@ import type { Host, Port } from '@/network/types'; +import ErrorPolykey from '@/ErrorPolykey'; import * as binUtils from '@/bin/utils/utils'; import * as nodesUtils from '@/nodes/utils'; -import * as errors from '@/errors'; +import * as grpcErrors from '@/grpc/errors'; import * as testUtils from '../utils'; describe('bin/utils', () => { @@ -81,11 +82,11 @@ describe('bin/utils', () => { const port = 55555 as Port; const nodeId = testUtils.generateRandomNodeId(); const standardError = new TypeError('some error'); - const pkError = new errors.ErrorPolykey('some pk error', { + const pkError = new ErrorPolykey('some pk error', { timestamp, data, }); - const remoteError = new errors.ErrorPolykeyRemote( + const remoteError = new grpcErrors.ErrorPolykeyRemote( { nodeId, host, @@ -95,7 +96,7 @@ describe('bin/utils', () => { 'some remote error', { timestamp, cause: pkError }, ); - const twoRemoteErrors = new errors.ErrorPolykeyRemote( + const twoRemoteErrors = new grpcErrors.ErrorPolykeyRemote( { nodeId, host, @@ -105,7 +106,7 @@ describe('bin/utils', () => { 'remote error', { timestamp, - cause: new errors.ErrorPolykeyRemote( + cause: new grpcErrors.ErrorPolykeyRemote( { nodeId, host, @@ -115,7 +116,7 @@ describe('bin/utils', () => { undefined, { timestamp, - cause: new errors.ErrorPolykey('pk error', { + cause: new ErrorPolykey('pk error', { timestamp, cause: standardError, }), diff --git a/tests/grpc/utils.test.ts b/tests/grpc/utils.test.ts index 7364d6bff..f757ee78e 100644 --- a/tests/grpc/utils.test.ts +++ b/tests/grpc/utils.test.ts @@ -74,7 +74,7 @@ describe('GRPC utils', () => { const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); const pCall = unary(messageTo); - await expect(pCall).rejects.toThrow(errors.ErrorPolykeyRemote); + await expect(pCall).rejects.toThrow(grpcErrors.ErrorPolykeyRemote); try { await pCall; } catch (e) { @@ -138,7 +138,7 @@ describe('GRPC utils', () => { messageTo.setChallenge(challenge); const stream = serverStream(messageTo); await expect(() => stream.next()).rejects.toThrow( - errors.ErrorPolykeyRemote, + grpcErrors.ErrorPolykeyRemote, ); // The generator will have ended // the internal stream will be automatically destroyed @@ -386,7 +386,7 @@ describe('GRPC utils', () => { messageTo.setChallenge('error'); await genDuplex.write(messageTo); await expect(() => genDuplex.read()).rejects.toThrow( - errors.ErrorPolykeyRemote, + grpcErrors.ErrorPolykeyRemote, ); expect(genDuplex.stream.destroyed).toBe(true); expect(genDuplex.stream.getPeer()).toBe(`127.0.0.1:${port}`); @@ -409,7 +409,7 @@ describe('GRPC utils', () => { const messageTo = new utilsPB.EchoMessage(); messageTo.setChallenge('error'); await expect(() => genDuplex.next(messageTo)).rejects.toThrow( - errors.ErrorPolykeyRemote, + grpcErrors.ErrorPolykeyRemote, ); expect(genDuplex.stream.destroyed).toBe(true); expect(genDuplex.stream.getPeer()).toBe(`127.0.0.1:${port}`); @@ -446,7 +446,7 @@ describe('GRPC utils', () => { command: 'testCall', }, ); - expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); + expect(deserialisedError).toBeInstanceOf(grpcErrors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); // @ts-ignore - already checked above that error is ErrorPolykeyRemote expect(deserialisedError.metadata.nodeId).toBe(nodeId); @@ -487,7 +487,7 @@ describe('GRPC utils', () => { command: 'testCall', }, ); - expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); + expect(deserialisedError).toBeInstanceOf(grpcErrors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); // @ts-ignore - already checked above that error is ErrorPolykeyRemote expect(deserialisedError.metadata.nodeId).toBe(nodeId); @@ -522,7 +522,7 @@ describe('GRPC utils', () => { command: 'testCall', }, ); - expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); + expect(deserialisedError).toBeInstanceOf(grpcErrors.ErrorPolykeyRemote); // @ts-ignore - already checked above that error is ErrorPolykeyRemote expect(deserialisedError.metadata.nodeId).toBe(nodeId); // @ts-ignore @@ -575,7 +575,7 @@ describe('GRPC utils', () => { command: 'testCall', }, ); - expect(deserialisedError).toBeInstanceOf(errors.ErrorPolykeyRemote); + expect(deserialisedError).toBeInstanceOf(grpcErrors.ErrorPolykeyRemote); expect(deserialisedError.message).toBe('test error'); // @ts-ignore - already checked above that error is ErrorPolykeyRemote expect(deserialisedError.metadata.nodeId).toBe(nodeId); diff --git a/tests/utils.ts b/tests/utils.ts index 38bd48fcd..311743565 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -12,8 +12,8 @@ import GRPCClientClient from '@/client/GRPCClientClient'; import * as clientUtils from '@/client/utils'; import * as keysUtils from '@/keys/utils'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; +import * as grpcErrors from '@/grpc/errors'; import { sleep } from '@/utils'; -import * as errors from '@/errors'; import config from '@/config'; /** @@ -189,7 +189,7 @@ const expectRemoteError = async ( promise: Promise, error, ): Promise => { - await expect(promise).rejects.toThrow(errors.ErrorPolykeyRemote); + await expect(promise).rejects.toThrow(grpcErrors.ErrorPolykeyRemote); try { return await promise; } catch (e) { From 66b527245897c561809db505f70c02610611f624 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Wed, 1 Jun 2022 15:26:27 +1000 Subject: [PATCH 67/74] fix: changed "remote error" to "cause" in cli error logging #323 --- src/bin/utils/utils.ts | 2 +- tests/bin/utils.test.ts | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/bin/utils/utils.ts b/src/bin/utils/utils.ts index 51b259dfb..1345afb04 100644 --- a/src/bin/utils/utils.ts +++ b/src/bin/utils/utils.ts @@ -119,7 +119,7 @@ function outputFormatter(msg: OutputObject): string { output += `${indent}host\t${currError.metadata.host}\n`; output += `${indent}port\t${currError.metadata.port}\n`; output += `${indent}timestamp\t${currError.timestamp}\n`; - output += `${indent}remote error: `; + output += `${indent}cause: `; currError = currError.cause; } else if (currError instanceof ErrorPolykey) { output += `${currError.name}: ${currError.description}`; diff --git a/tests/bin/utils.test.ts b/tests/bin/utils.test.ts index 80b9aa3bf..6a53667da 100644 --- a/tests/bin/utils.test.ts +++ b/tests/bin/utils.test.ts @@ -124,7 +124,7 @@ describe('bin/utils', () => { ), }, ); - // Error + // Human expect( binUtils.outputFormatter({ type: 'error', data: standardError }), ).toBe(`${standardError.name}: ${standardError.message}\n`); @@ -141,7 +141,7 @@ describe('bin/utils', () => { ` host\t${host}\n` + ` port\t${port}\n` + ` timestamp\t${timestamp.toString()}\n` + - ` remote error: ${remoteError.cause.name}: ${remoteError.cause.description} - ${remoteError.cause.message}\n` + + ` cause: ${remoteError.cause.name}: ${remoteError.cause.description} - ${remoteError.cause.message}\n` + ` exitCode\t${pkError.exitCode}\n` + ` timestamp\t${timestamp.toString()}\n` + ` data\t${JSON.stringify(data)}\n`, @@ -155,17 +155,18 @@ describe('bin/utils', () => { ` host\t${host}\n` + ` port\t${port}\n` + ` timestamp\t${timestamp.toString()}\n` + - ` remote error: ${twoRemoteErrors.cause.name}: ${twoRemoteErrors.cause.description}\n` + + ` cause: ${twoRemoteErrors.cause.name}: ${twoRemoteErrors.cause.description}\n` + ` command\t${twoRemoteErrors.cause.metadata.command}\n` + ` nodeId\t${nodesUtils.encodeNodeId(nodeId)}\n` + ` host\t${host}\n` + ` port\t${port}\n` + ` timestamp\t${timestamp.toString()}\n` + - ` remote error: ${twoRemoteErrors.cause.cause.name}: ${twoRemoteErrors.cause.cause.description} - ${twoRemoteErrors.cause.cause.message}\n` + + ` cause: ${twoRemoteErrors.cause.cause.name}: ${twoRemoteErrors.cause.cause.description} - ${twoRemoteErrors.cause.cause.message}\n` + ` exitCode\t${pkError.exitCode}\n` + ` timestamp\t${timestamp.toString()}\n` + ` cause: ${standardError.name}: ${standardError.message}\n`, ); + // JSON expect( binUtils.outputFormatter({ type: 'json', data: standardError }), ).toBe( From 4e99b8bf7636bce1bb4e3ab7dd318af94d6d9a2b Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Wed, 1 Jun 2022 17:08:36 +1000 Subject: [PATCH 68/74] feat: filtering error logging in service handlers We only want to log out server errors on the server side, so we now apply filters on errors before logging them. --- src/agent/service/nodesChainDataGet.ts | 3 +- .../service/nodesClosestLocalNodesGet.ts | 3 +- src/agent/service/nodesCrossSignClaim.ts | 9 ++- .../service/nodesHolePunchMessageSend.ts | 3 +- src/agent/service/notificationsSend.ts | 9 ++- src/agent/service/vaultsGitInfoGet.ts | 64 +++++++++------- src/agent/service/vaultsGitPackGet.ts | 55 +++++++++----- src/agent/service/vaultsScan.ts | 9 ++- src/agent/utils.ts | 37 ++++++++- src/client/service/agentLockAll.ts | 3 +- src/client/service/agentStatus.ts | 3 +- src/client/service/agentStop.ts | 3 +- src/client/service/agentUnlock.ts | 3 +- .../service/gestaltsActionsGetByIdentity.ts | 6 +- .../service/gestaltsActionsGetByNode.ts | 3 +- .../service/gestaltsActionsSetByIdentity.ts | 7 +- .../service/gestaltsActionsSetByNode.ts | 6 +- .../service/gestaltsActionsUnsetByIdentity.ts | 7 +- .../service/gestaltsActionsUnsetByNode.ts | 6 +- .../service/gestaltsDiscoveryByIdentity.ts | 3 +- src/client/service/gestaltsDiscoveryByNode.ts | 3 +- .../service/gestaltsGestaltGetByIdentity.ts | 3 +- .../service/gestaltsGestaltGetByNode.ts | 3 +- src/client/service/gestaltsGestaltList.ts | 3 +- .../service/gestaltsGestaltTrustByIdentity.ts | 7 +- .../service/gestaltsGestaltTrustByNode.ts | 6 +- src/client/service/identitiesAuthenticate.ts | 4 +- .../service/identitiesAuthenticatedGet.ts | 3 +- src/client/service/identitiesClaim.ts | 6 +- .../service/identitiesInfoConnectedGet.ts | 7 +- src/client/service/identitiesInfoGet.ts | 6 +- src/client/service/identitiesProvidersList.ts | 3 +- src/client/service/identitiesTokenDelete.ts | 3 +- src/client/service/identitiesTokenGet.ts | 3 +- src/client/service/identitiesTokenPut.ts | 3 +- src/client/service/keysCertsChainGet.ts | 3 +- src/client/service/keysCertsGet.ts | 3 +- src/client/service/keysDecrypt.ts | 3 +- src/client/service/keysEncrypt.ts | 3 +- src/client/service/keysKeyPairRenew.ts | 3 +- src/client/service/keysKeyPairReset.ts | 3 +- src/client/service/keysKeyPairRoot.ts | 3 +- src/client/service/keysPasswordChange.ts | 3 +- src/client/service/keysSign.ts | 3 +- src/client/service/keysVerify.ts | 3 +- src/client/service/nodesAdd.ts | 3 +- src/client/service/nodesClaim.ts | 6 +- src/client/service/nodesFind.ts | 6 +- src/client/service/nodesPing.ts | 6 +- src/client/service/notificationsClear.ts | 3 +- src/client/service/notificationsRead.ts | 3 +- src/client/service/notificationsSend.ts | 6 +- src/client/service/vaultsClone.ts | 51 ++++++++----- src/client/service/vaultsCreate.ts | 5 +- src/client/service/vaultsDelete.ts | 34 +++++++-- src/client/service/vaultsList.ts | 3 +- src/client/service/vaultsLog.ts | 48 ++++++++---- src/client/service/vaultsPermissionGet.ts | 37 ++++++--- src/client/service/vaultsPermissionSet.ts | 68 +++++++++++------ src/client/service/vaultsPermissionUnset.ts | 61 ++++++++++----- src/client/service/vaultsPull.ts | 75 +++++++++++-------- src/client/service/vaultsRename.ts | 44 +++++++---- src/client/service/vaultsScan.ts | 8 +- src/client/service/vaultsSecretsDelete.ts | 42 ++++++++--- src/client/service/vaultsSecretsEdit.ts | 52 ++++++++----- src/client/service/vaultsSecretsGet.ts | 42 ++++++++--- src/client/service/vaultsSecretsList.ts | 34 +++++++-- src/client/service/vaultsSecretsMkdir.ts | 47 ++++++++---- src/client/service/vaultsSecretsNew.ts | 42 ++++++++--- src/client/service/vaultsSecretsNewDir.ts | 40 +++++++--- src/client/service/vaultsSecretsRename.ts | 52 ++++++++----- src/client/service/vaultsSecretsStat.ts | 42 ++++++++--- src/client/service/vaultsVersion.ts | 47 ++++++++---- src/client/utils/utils.ts | 37 +++++++++ 74 files changed, 903 insertions(+), 376 deletions(-) diff --git a/src/agent/service/nodesChainDataGet.ts b/src/agent/service/nodesChainDataGet.ts index 492c8ca73..0e09ff35f 100644 --- a/src/agent/service/nodesChainDataGet.ts +++ b/src/agent/service/nodesChainDataGet.ts @@ -6,6 +6,7 @@ import type { ClaimIdEncoded } from '../../claims/types'; import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; +import * as agentUtils from '../utils'; /** * Retrieves the ChainDataEncoded of this node. @@ -50,7 +51,7 @@ function nodesChainDataGet({ return; } catch (e) { callback(grpcUtils.fromError(e, true)); - logger.error(e); + !agentUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/agent/service/nodesClosestLocalNodesGet.ts b/src/agent/service/nodesClosestLocalNodesGet.ts index bd562bbe5..e28fbd191 100644 --- a/src/agent/service/nodesClosestLocalNodesGet.ts +++ b/src/agent/service/nodesClosestLocalNodesGet.ts @@ -9,6 +9,7 @@ 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'; +import * as agentUtils from '../utils'; /** * Retrieves the local nodes (i.e. from the current node) that are closest @@ -66,7 +67,7 @@ function nodesClosestLocalNodesGet({ return; } catch (e) { callback(grpcUtils.fromError(e, true)); - logger.error(e); + !agentUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index f9fbb1bbb..63b6304c9 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -14,6 +14,7 @@ import * as nodesUtils from '../../nodes/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import { matchSync } from '../../utils'; +import * as agentUtils from '../utils'; function nodesCrossSignClaim({ db, @@ -172,7 +173,13 @@ function nodesCrossSignClaim({ }); } catch (e) { await genClaims.throw(e); - logger.error(e); + !agentUtils.isClientError(e, [ + claimsErrors.ErrorEmptyStream, + claimsErrors.ErrorUndefinedSinglySignedClaim, + claimsErrors.ErrorUndefinedSignature, + claimsErrors.ErrorNodesClaimType, + claimsErrors.ErrorUndefinedDoublySignedClaim, + ]) && logger.error(e); return; } }; diff --git a/src/agent/service/nodesHolePunchMessageSend.ts b/src/agent/service/nodesHolePunchMessageSend.ts index c1b681054..1ec86a35c 100644 --- a/src/agent/service/nodesHolePunchMessageSend.ts +++ b/src/agent/service/nodesHolePunchMessageSend.ts @@ -12,6 +12,7 @@ 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'; +import * as agentUtils from '../utils'; function nodesHolePunchMessageSend({ keyManager, @@ -73,7 +74,7 @@ function nodesHolePunchMessageSend({ return; } catch (e) { callback(grpcUtils.fromError(e, true)); - logger.error(e); + !agentUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/agent/service/notificationsSend.ts b/src/agent/service/notificationsSend.ts index 07aaf0933..6108cbe74 100644 --- a/src/agent/service/notificationsSend.ts +++ b/src/agent/service/notificationsSend.ts @@ -5,7 +5,9 @@ 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 notificationsErrors from '../../notifications/errors'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as agentUtils from '../utils'; function notificationsSend({ notificationsManager, @@ -34,7 +36,12 @@ function notificationsSend({ return; } catch (e) { callback(grpcUtils.fromError(e, true)); - logger.error(e); + !agentUtils.isClientError(e, [ + notificationsErrors.ErrorNotificationsInvalidType, + notificationsErrors.ErrorNotificationsValidationFailed, + notificationsErrors.ErrorNotificationsParse, + notificationsErrors.ErrorNotificationsPermissionsNotFound, + ]) && logger.error(e); return; } }; diff --git a/src/agent/service/vaultsGitInfoGet.ts b/src/agent/service/vaultsGitInfoGet.ts index 4a9893985..aecdde37e 100644 --- a/src/agent/service/vaultsGitInfoGet.ts +++ b/src/agent/service/vaultsGitInfoGet.ts @@ -1,5 +1,5 @@ import type { DB } from '@matrixai/db'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId, VaultAction } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type ACL from '../../acl/ACL'; import type { ConnectionInfoGet } from '../../agent/types'; @@ -9,9 +9,12 @@ import * as grpcUtils from '../../grpc/utils'; import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as nodesUtils from '../../nodes/utils'; +import { matchSync } from '../../utils'; import * as agentErrors from '../errors'; +import * as agentUtils from '../utils'; function vaultsGitInfoGet({ vaultManager, @@ -31,29 +34,37 @@ function vaultsGitInfoGet({ ): Promise => { 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, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() 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, - }); - } + const { + vaultId, + actionType, + }: { + vaultId: VaultId; + actionType: VaultAction; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + [['actionType'], () => validationUtils.parseVaultAction(value)], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + actionType: call.request.getAction(), + }, + ); + const vaultName = (await vaultManager.getVaultMeta(vaultId, tran)) + ?.vaultName; + if (vaultName == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); } // Getting the NodeId from the ReverseProxy connection info const connectionInfo = connectionInfoGet(call); @@ -64,9 +75,6 @@ function vaultsGitInfoGet({ } 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( @@ -97,9 +105,15 @@ function vaultsGitInfoGet({ } }); await genWritable.next(null); + return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !agentUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + agentErrors.ErrorConnectionInfoMissing, + vaultsErrors.ErrorVaultsPermissionDenied, + ]) && logger.error(e); + return; } }; } diff --git a/src/agent/service/vaultsGitPackGet.ts b/src/agent/service/vaultsGitPackGet.ts index c7ec95dbd..e17cad29f 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -1,19 +1,21 @@ import type * as grpc from '@grpc/grpc-js'; import type { DB } from '@matrixai/db'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId, VaultAction } 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'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultsUtils from '../../vaults/utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import { matchSync } from '../../utils'; import * as agentErrors from '../errors'; +import * as agentUtils from '../utils'; function vaultsGitPackGet({ vaultManager, @@ -54,29 +56,36 @@ function vaultsGitPackGet({ } 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, + const vaultIdFromName = await vaultManager.getVaultId( + meta.get('vaultNameOrId').pop()!.toString() 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}`, - ); - } + const { + vaultId, + actionType, + }: { + vaultId: VaultId; + actionType: VaultAction; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + [['actionType'], () => validationUtils.parseVaultAction(value)], + () => value, + ); + }, + { + vaultId: meta.get('vaultNameOrId').pop(), + actionType: meta.get('vaultAction').pop(), + }, + ); // 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( @@ -110,9 +119,15 @@ function vaultsGitPackGet({ }); }); await genDuplex.next(null); + return; } catch (e) { await genDuplex.throw(e); - logger.error(e); + !agentUtils.isClientError(e, [ + agentErrors.ErrorConnectionInfoMissing, + vaultsErrors.ErrorVaultsPermissionDenied, + vaultsErrors.ErrorVaultsVaultUndefined, + ]) && logger.error(e); + return; } }; } diff --git a/src/agent/service/vaultsScan.ts b/src/agent/service/vaultsScan.ts index 2fd04d5e5..42e6ca8eb 100644 --- a/src/agent/service/vaultsScan.ts +++ b/src/agent/service/vaultsScan.ts @@ -5,9 +5,11 @@ 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 vaultsErrors from '../../vaults/errors'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as agentUtils from '../utils'; function vaultsScan({ vaultManager, @@ -48,9 +50,14 @@ function vaultsScan({ } }); await genWritable.next(null); + return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !agentUtils.isClientError(e, [ + agentErrors.ErrorConnectionInfoMissing, + vaultsErrors.ErrorVaultsPermissionDenied, + ]) && logger.error(e); + return; } }; } diff --git a/src/agent/utils.ts b/src/agent/utils.ts index f38e540d5..94b7d97d5 100644 --- a/src/agent/utils.ts +++ b/src/agent/utils.ts @@ -1,7 +1,17 @@ +import type { ServerSurfaceCall } from '@grpc/grpc-js/build/src/server-call'; +import type { Class } from '@matrixai/errors'; import type { Host, Port } from 'network/types'; import type Proxy from 'network/Proxy'; import type { ConnectionInfoGet } from './types'; -import type { ServerSurfaceCall } from '@grpc/grpc-js/build/src/server-call'; +import * as validationErrors from '../validation/errors'; + +/** + * Array of errors that are always considered to be "client errors" + * (4xx errors in HTTP) in the context of the agent service + */ +const defaultClientErrors: Array> = [ + validationErrors.ErrorValidation, +]; function connectionInfoGetter(proxy: Proxy): ConnectionInfoGet { return (call: ServerSurfaceCall) => { @@ -15,4 +25,27 @@ function connectionInfoGetter(proxy: Proxy): ConnectionInfoGet { }; } -export { connectionInfoGetter }; +/** + * Checks whether an error is a "client error" (4xx errors in HTTP) + * Used by the service handlers since client errors should not be + * reported on the server side + * Additional errors that are considered to be client errors in the + * context of a given handler can be supplied in the `extraClientErrors` + * argument + */ +function isClientError( + e: Error, + extraClientErrors?: Array>, +): boolean { + for (const error of defaultClientErrors) { + if (e instanceof error) return true; + } + if (extraClientErrors) { + for (const error of extraClientErrors) { + if (e instanceof error) return true; + } + } + return false; +} + +export { connectionInfoGetter, isClientError }; diff --git a/src/client/service/agentLockAll.ts b/src/client/service/agentLockAll.ts index 1bc011b08..90ad0a93a 100644 --- a/src/client/service/agentLockAll.ts +++ b/src/client/service/agentLockAll.ts @@ -5,6 +5,7 @@ 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'; +import * as clientUtils from '../utils'; function agentLockAll({ authenticate, @@ -32,7 +33,7 @@ function agentLockAll({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/agentStatus.ts b/src/client/service/agentStatus.ts index ecac4e1c1..52d14144a 100644 --- a/src/client/service/agentStatus.ts +++ b/src/client/service/agentStatus.ts @@ -9,6 +9,7 @@ import process from 'process'; import * as grpcUtils from '../../grpc/utils'; import * as nodesUtils from '../../nodes/utils'; import * as agentPB from '../../proto/js/polykey/v1/agent/agent_pb'; +import * as clientUtils from '../utils'; function agentStatus({ authenticate, @@ -49,7 +50,7 @@ function agentStatus({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/agentStop.ts b/src/client/service/agentStop.ts index f359036b8..a745887e5 100644 --- a/src/client/service/agentStop.ts +++ b/src/client/service/agentStop.ts @@ -5,6 +5,7 @@ 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'; +import * as clientUtils from '../utils'; function agentStop({ authenticate, @@ -32,7 +33,7 @@ function agentStop({ callback(null, response); } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(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 1814eb81a..1f726792d 100644 --- a/src/client/service/agentUnlock.ts +++ b/src/client/service/agentUnlock.ts @@ -3,6 +3,7 @@ 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'; +import * as clientUtils from '../utils'; function agentUnlock({ authenticate, @@ -23,7 +24,7 @@ function agentUnlock({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsGetByIdentity.ts b/src/client/service/gestaltsActionsGetByIdentity.ts index a1ee40c4a..bd0d8ba04 100644 --- a/src/client/service/gestaltsActionsGetByIdentity.ts +++ b/src/client/service/gestaltsActionsGetByIdentity.ts @@ -8,9 +8,9 @@ import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identit 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'; +import * as clientUtils from '../utils'; function gestaltsActionsGetByIdentity({ authenticate, @@ -63,9 +63,7 @@ function gestaltsActionsGetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - if (!(e instanceof validationErrors.ErrorValidation)) { - logger.error(e); - } + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsGetByNode.ts b/src/client/service/gestaltsActionsGetByNode.ts index 77ad8360a..11187384b 100644 --- a/src/client/service/gestaltsActionsGetByNode.ts +++ b/src/client/service/gestaltsActionsGetByNode.ts @@ -10,6 +10,7 @@ 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'; +import * as clientUtils from '../utils'; function gestaltsActionsGetByNode({ authenticate, @@ -56,7 +57,7 @@ function gestaltsActionsGetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsSetByIdentity.ts b/src/client/service/gestaltsActionsSetByIdentity.ts index b0975d562..3776bbebb 100644 --- a/src/client/service/gestaltsActionsSetByIdentity.ts +++ b/src/client/service/gestaltsActionsSetByIdentity.ts @@ -9,8 +9,10 @@ import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as gestaltsErrors from '../../gestalts/errors'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; function gestaltsActionsSetByIdentity({ authenticate, @@ -66,7 +68,10 @@ function gestaltsActionsSetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, + gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsSetByNode.ts b/src/client/service/gestaltsActionsSetByNode.ts index 917e3b198..91cef278f 100644 --- a/src/client/service/gestaltsActionsSetByNode.ts +++ b/src/client/service/gestaltsActionsSetByNode.ts @@ -9,8 +9,10 @@ import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as gestaltsErrors from '../../gestalts/errors'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; function gestaltsActionsSetByNode({ authenticate, @@ -52,7 +54,9 @@ function gestaltsActionsSetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsUnsetByIdentity.ts b/src/client/service/gestaltsActionsUnsetByIdentity.ts index cb976d117..1b20a5610 100644 --- a/src/client/service/gestaltsActionsUnsetByIdentity.ts +++ b/src/client/service/gestaltsActionsUnsetByIdentity.ts @@ -9,8 +9,10 @@ import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as gestaltsErrors from '../../gestalts/errors'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; function gestaltsActionsUnsetByIdentity({ authenticate, @@ -66,7 +68,10 @@ function gestaltsActionsUnsetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, + gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsUnsetByNode.ts b/src/client/service/gestaltsActionsUnsetByNode.ts index 2bc5d410f..1f06d2c64 100644 --- a/src/client/service/gestaltsActionsUnsetByNode.ts +++ b/src/client/service/gestaltsActionsUnsetByNode.ts @@ -9,8 +9,10 @@ import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as gestaltsErrors from '../../gestalts/errors'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; function gestaltsActionsUnsetByNode({ authenticate, @@ -52,7 +54,9 @@ function gestaltsActionsUnsetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsDiscoveryByIdentity.ts b/src/client/service/gestaltsDiscoveryByIdentity.ts index 9834d4e7c..b63bb83bf 100644 --- a/src/client/service/gestaltsDiscoveryByIdentity.ts +++ b/src/client/service/gestaltsDiscoveryByIdentity.ts @@ -9,6 +9,7 @@ import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; import * as validationUtils from '../../validation/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; function gestaltsDiscoveryByIdentity({ authenticate, @@ -51,7 +52,7 @@ function gestaltsDiscoveryByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsDiscoveryByNode.ts b/src/client/service/gestaltsDiscoveryByNode.ts index ed8ab18e6..b37bd777c 100644 --- a/src/client/service/gestaltsDiscoveryByNode.ts +++ b/src/client/service/gestaltsDiscoveryByNode.ts @@ -9,6 +9,7 @@ import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; import * as validationUtils from '../../validation/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; function gestaltsDiscoveryByNode({ authenticate, @@ -47,7 +48,7 @@ function gestaltsDiscoveryByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltGetByIdentity.ts b/src/client/service/gestaltsGestaltGetByIdentity.ts index 4e4a25d78..9396c3d6d 100644 --- a/src/client/service/gestaltsGestaltGetByIdentity.ts +++ b/src/client/service/gestaltsGestaltGetByIdentity.ts @@ -10,6 +10,7 @@ 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'; +import * as clientUtils from '../utils'; function gestaltsGestaltGetByIdentity({ authenticate, @@ -59,7 +60,7 @@ function gestaltsGestaltGetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltGetByNode.ts b/src/client/service/gestaltsGestaltGetByNode.ts index 28fc02c3f..2fbbb8447 100644 --- a/src/client/service/gestaltsGestaltGetByNode.ts +++ b/src/client/service/gestaltsGestaltGetByNode.ts @@ -10,6 +10,7 @@ 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'; +import * as clientUtils from '../utils'; function gestaltsGestaltGetByNode({ authenticate, @@ -55,7 +56,7 @@ function gestaltsGestaltGetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltList.ts b/src/client/service/gestaltsGestaltList.ts index bb96dd53a..cbe2e0027 100644 --- a/src/client/service/gestaltsGestaltList.ts +++ b/src/client/service/gestaltsGestaltList.ts @@ -7,6 +7,7 @@ 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 gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; +import * as clientUtils from '../utils'; function gestaltsGestaltList({ authenticate, @@ -39,7 +40,7 @@ function gestaltsGestaltList({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltTrustByIdentity.ts b/src/client/service/gestaltsGestaltTrustByIdentity.ts index 71368e7fb..9fc7c4911 100644 --- a/src/client/service/gestaltsGestaltTrustByIdentity.ts +++ b/src/client/service/gestaltsGestaltTrustByIdentity.ts @@ -9,8 +9,10 @@ import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; +import * as gestaltsErrors from '../../gestalts/errors'; import * as validationUtils from '../../validation/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; function gestaltsGestaltTrustByIdentity({ authenticate, @@ -82,7 +84,10 @@ function gestaltsGestaltTrustByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, + gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltTrustByNode.ts b/src/client/service/gestaltsGestaltTrustByNode.ts index 097a94b07..9be7fa628 100644 --- a/src/client/service/gestaltsGestaltTrustByNode.ts +++ b/src/client/service/gestaltsGestaltTrustByNode.ts @@ -9,9 +9,11 @@ import type Logger from '@matrixai/logger'; import { validateSync } from '../../validation'; import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; +import * as gestaltsErrors from '../../gestalts/errors'; import * as validationUtils from '../../validation/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; import * as nodesUtils from '../../nodes/utils'; +import * as clientUtils from '../utils'; function gestaltsGestaltTrustByNode({ authenticate, @@ -69,7 +71,9 @@ function gestaltsGestaltTrustByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesAuthenticate.ts b/src/client/service/identitiesAuthenticate.ts index 05c3e05d3..9aa0927e0 100644 --- a/src/client/service/identitiesAuthenticate.ts +++ b/src/client/service/identitiesAuthenticate.ts @@ -9,6 +9,7 @@ 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'; +import * as clientUtils from '../utils'; function identitiesAuthenticate({ authenticate, @@ -74,7 +75,8 @@ function identitiesAuthenticate({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e, [identitiesErrors.ErrorProviderMissing]) && + logger.error(e); return; } }; diff --git a/src/client/service/identitiesAuthenticatedGet.ts b/src/client/service/identitiesAuthenticatedGet.ts index 82262f89d..64d0d7232 100644 --- a/src/client/service/identitiesAuthenticatedGet.ts +++ b/src/client/service/identitiesAuthenticatedGet.ts @@ -8,6 +8,7 @@ import { matchSync } from '../../utils'; import * as grpcUtils from '../../grpc/utils'; import * as validationUtils from '../../validation/utils'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; +import * as clientUtils from '../utils'; function identitiesAuthenticatedGet({ authenticate, @@ -63,7 +64,7 @@ function identitiesAuthenticatedGet({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesClaim.ts b/src/client/service/identitiesClaim.ts index 43919bd45..884a5ca1c 100644 --- a/src/client/service/identitiesClaim.ts +++ b/src/client/service/identitiesClaim.ts @@ -14,6 +14,7 @@ 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'; +import * as clientUtils from '../utils'; /** * Augments the keynode with a new identity. @@ -92,7 +93,10 @@ function identitiesClaim({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + identitiesErrors.ErrorProviderMissing, + identitiesErrors.ErrorProviderUnauthenticated, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesInfoConnectedGet.ts b/src/client/service/identitiesInfoConnectedGet.ts index b9d7ac441..7ac96810c 100644 --- a/src/client/service/identitiesInfoConnectedGet.ts +++ b/src/client/service/identitiesInfoConnectedGet.ts @@ -13,6 +13,7 @@ import * as grpcUtils from '../../grpc/utils'; import * as validationUtils from '../../validation/utils'; import * as identitiesErrors from '../../identities/errors'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; +import * as clientUtils from '../utils'; function identitiesInfoConnectedGet({ authenticate, @@ -119,7 +120,11 @@ function identitiesInfoConnectedGet({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e, [ + identitiesErrors.ErrorProviderMissing, + identitiesErrors.ErrorProviderUnauthenticated, + identitiesErrors.ErrorProviderUnimplemented, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesInfoGet.ts b/src/client/service/identitiesInfoGet.ts index 5f456dac5..bd29cf2f3 100644 --- a/src/client/service/identitiesInfoGet.ts +++ b/src/client/service/identitiesInfoGet.ts @@ -14,6 +14,7 @@ import * as validationUtils from '../../validation/utils'; import * as identitiesUtils from '../../identities/utils'; import * as identitiesErrors from '../../identities/errors'; import * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; +import * as clientUtils from '../utils'; function identitiesInfoGet({ authenticate, @@ -112,7 +113,10 @@ function identitiesInfoGet({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e, [ + identitiesErrors.ErrorProviderMissing, + identitiesErrors.ErrorProviderUnauthenticated, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesProvidersList.ts b/src/client/service/identitiesProvidersList.ts index 35751c3fb..cd451d2f9 100644 --- a/src/client/service/identitiesProvidersList.ts +++ b/src/client/service/identitiesProvidersList.ts @@ -5,6 +5,7 @@ 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 identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb'; +import * as clientUtils from '../utils'; function identitiesProvidersList({ authenticate, @@ -29,7 +30,7 @@ function identitiesProvidersList({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenDelete.ts b/src/client/service/identitiesTokenDelete.ts index 82d0d57d5..9abe9d624 100644 --- a/src/client/service/identitiesTokenDelete.ts +++ b/src/client/service/identitiesTokenDelete.ts @@ -10,6 +10,7 @@ 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'; +import * as clientUtils from '../utils'; function identitiesTokenDelete({ authenticate, @@ -56,7 +57,7 @@ function identitiesTokenDelete({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenGet.ts b/src/client/service/identitiesTokenGet.ts index 09199866d..193cf2553 100644 --- a/src/client/service/identitiesTokenGet.ts +++ b/src/client/service/identitiesTokenGet.ts @@ -9,6 +9,7 @@ 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'; +import * as clientUtils from '../utils'; function identitiesTokenGet({ authenticate, @@ -56,7 +57,7 @@ function identitiesTokenGet({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenPut.ts b/src/client/service/identitiesTokenPut.ts index 336f1646a..c06ad8106 100644 --- a/src/client/service/identitiesTokenPut.ts +++ b/src/client/service/identitiesTokenPut.ts @@ -10,6 +10,7 @@ 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'; +import * as clientUtils from '../utils'; function identitiesTokenPut({ authenticate, @@ -66,7 +67,7 @@ function identitiesTokenPut({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysCertsChainGet.ts b/src/client/service/keysCertsChainGet.ts index 6290a313c..94418b7b6 100644 --- a/src/client/service/keysCertsChainGet.ts +++ b/src/client/service/keysCertsChainGet.ts @@ -5,6 +5,7 @@ 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 keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; +import * as clientUtils from '../utils'; function keysCertsChainGet({ authenticate, @@ -33,7 +34,7 @@ function keysCertsChainGet({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysCertsGet.ts b/src/client/service/keysCertsGet.ts index eabde463b..da8792aa1 100644 --- a/src/client/service/keysCertsGet.ts +++ b/src/client/service/keysCertsGet.ts @@ -5,6 +5,7 @@ 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 keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; +import * as clientUtils from '../utils'; function keysCertsGet({ authenticate, @@ -29,7 +30,7 @@ function keysCertsGet({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysDecrypt.ts b/src/client/service/keysDecrypt.ts index ed1776cda..092e7f67b 100644 --- a/src/client/service/keysDecrypt.ts +++ b/src/client/service/keysDecrypt.ts @@ -4,6 +4,7 @@ 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'; +import * as clientUtils from '../utils'; function keysDecrypt({ authenticate, @@ -30,7 +31,7 @@ function keysDecrypt({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysEncrypt.ts b/src/client/service/keysEncrypt.ts index 35159f870..df8f4ff62 100644 --- a/src/client/service/keysEncrypt.ts +++ b/src/client/service/keysEncrypt.ts @@ -4,6 +4,7 @@ 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'; +import * as clientUtils from '../utils'; function keysEncrypt({ authenticate, @@ -30,7 +31,7 @@ function keysEncrypt({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairRenew.ts b/src/client/service/keysKeyPairRenew.ts index dcd90d7c1..3660c9bc5 100644 --- a/src/client/service/keysKeyPairRenew.ts +++ b/src/client/service/keysKeyPairRenew.ts @@ -5,6 +5,7 @@ import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_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 clientUtils from '../utils'; function keysKeyPairRenew({ authenticate, @@ -30,7 +31,7 @@ function keysKeyPairRenew({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairReset.ts b/src/client/service/keysKeyPairReset.ts index 87498f733..3d04f12aa 100644 --- a/src/client/service/keysKeyPairReset.ts +++ b/src/client/service/keysKeyPairReset.ts @@ -5,6 +5,7 @@ import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_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 clientUtils from '../utils'; function keysKeyPairReset({ authenticate, @@ -30,7 +31,7 @@ function keysKeyPairReset({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairRoot.ts b/src/client/service/keysKeyPairRoot.ts index 7bfc95549..ad1eb3e5a 100644 --- a/src/client/service/keysKeyPairRoot.ts +++ b/src/client/service/keysKeyPairRoot.ts @@ -5,6 +5,7 @@ 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 keysPB from '../../proto/js/polykey/v1/keys/keys_pb'; +import * as clientUtils from '../utils'; function keysKeyPairRoot({ authenticate, @@ -30,7 +31,7 @@ function keysKeyPairRoot({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysPasswordChange.ts b/src/client/service/keysPasswordChange.ts index 639e60ac9..b96a44ca1 100644 --- a/src/client/service/keysPasswordChange.ts +++ b/src/client/service/keysPasswordChange.ts @@ -5,6 +5,7 @@ import type * as sessionsPB from '../../proto/js/polykey/v1/sessions/sessions_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 clientUtils from '../utils'; function keysPasswordChange({ authenticate, @@ -28,7 +29,7 @@ function keysPasswordChange({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysSign.ts b/src/client/service/keysSign.ts index b998e0561..bae99915f 100644 --- a/src/client/service/keysSign.ts +++ b/src/client/service/keysSign.ts @@ -4,6 +4,7 @@ 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'; +import * as clientUtils from '../utils'; function keysSign({ authenticate, @@ -31,7 +32,7 @@ function keysSign({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysVerify.ts b/src/client/service/keysVerify.ts index efbfb7b4c..a7cfaae3a 100644 --- a/src/client/service/keysVerify.ts +++ b/src/client/service/keysVerify.ts @@ -5,6 +5,7 @@ import type * as keysPB from '../../proto/js/polykey/v1/keys/keys_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 clientUtils from '../utils'; function keysVerify({ authenticate, @@ -32,7 +33,7 @@ function keysVerify({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/nodesAdd.ts b/src/client/service/nodesAdd.ts index 1433e0896..8c089ff0b 100644 --- a/src/client/service/nodesAdd.ts +++ b/src/client/service/nodesAdd.ts @@ -11,6 +11,7 @@ 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'; +import * as clientUtils from '../utils'; /** * Adds a node ID -> node address mapping into the buckets database. @@ -73,7 +74,7 @@ function nodesAdd({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/nodesClaim.ts b/src/client/service/nodesClaim.ts index 4d9cdc783..4022e10c7 100644 --- a/src/client/service/nodesClaim.ts +++ b/src/client/service/nodesClaim.ts @@ -9,8 +9,10 @@ import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as nodesErrors from '../../nodes/errors'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; /** * Checks whether there is an existing Gestalt Invitation from the other node. @@ -75,7 +77,9 @@ function nodesClaim({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + nodesErrors.ErrorNodeGraphNodeIdNotFound, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/nodesFind.ts b/src/client/service/nodesFind.ts index 284e50748..4826f9d96 100644 --- a/src/client/service/nodesFind.ts +++ b/src/client/service/nodesFind.ts @@ -4,11 +4,13 @@ import type NodeConnectionManager from '../../nodes/NodeConnectionManager'; import type { NodeId } from '../../nodes/types'; import type Logger from '@matrixai/logger'; import * as nodesUtils from '../../nodes/utils'; +import * as nodesErrors from '../../nodes/errors'; 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'; +import * as clientUtils from '../utils'; /** * Attempts to get the node address of a provided node ID (by contacting @@ -57,7 +59,9 @@ function nodesFind({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + nodesErrors.ErrorNodeGraphNodeIdNotFound, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/nodesPing.ts b/src/client/service/nodesPing.ts index 449905cc7..f86c8c1fa 100644 --- a/src/client/service/nodesPing.ts +++ b/src/client/service/nodesPing.ts @@ -7,8 +7,10 @@ import type Logger from '@matrixai/logger'; import * as grpcUtils from '../../grpc/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as nodesErrors from '../../nodes/errors'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; /** * Checks if a remote node is online. @@ -51,7 +53,9 @@ function nodesPing({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + nodesErrors.ErrorNodeGraphNodeIdNotFound, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/notificationsClear.ts b/src/client/service/notificationsClear.ts index 56b2fabef..8d1d501c1 100644 --- a/src/client/service/notificationsClear.ts +++ b/src/client/service/notificationsClear.ts @@ -5,6 +5,7 @@ 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'; +import * as clientUtils from '../utils'; function notificationsClear({ authenticate, @@ -32,7 +33,7 @@ function notificationsClear({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/notificationsRead.ts b/src/client/service/notificationsRead.ts index 63b94438d..60d55b7c7 100644 --- a/src/client/service/notificationsRead.ts +++ b/src/client/service/notificationsRead.ts @@ -5,6 +5,7 @@ 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'; +import * as clientUtils from '../utils'; function notificationsRead({ authenticate, @@ -74,7 +75,7 @@ function notificationsRead({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/notificationsSend.ts b/src/client/service/notificationsSend.ts index 4ff96fea6..c592aa476 100644 --- a/src/client/service/notificationsSend.ts +++ b/src/client/service/notificationsSend.ts @@ -8,8 +8,10 @@ import * as grpcUtils from '../../grpc/utils'; import * as notificationsUtils from '../../notifications/utils'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as nodesErrors from '../../nodes/errors'; import { matchSync } from '../../utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as clientUtils from '../utils'; function notificationsSend({ authenticate, @@ -54,7 +56,9 @@ function notificationsSend({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + nodesErrors.ErrorNodeGraphNodeIdNotFound, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsClone.ts b/src/client/service/vaultsClone.ts index bd3693c5c..4e931e551 100644 --- a/src/client/service/vaultsClone.ts +++ b/src/client/service/vaultsClone.ts @@ -1,13 +1,20 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; +import type { VaultId } from '../../vaults/types'; +import type { NodeId } from '../../nodes/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 type * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import * as nodesErrors from '../../nodes/errors'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as vaultsUtils from '../../vaults/utils'; +import * as vaultsErrors from '../../vaults/errors'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsClone({ authenticate, @@ -28,24 +35,25 @@ function vaultsClone({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - - const vaultMessage = call.request.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nodeMessage = call.request.getNode(); - if (nodeMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - // Vault id - let vaultId; - const vaultNameOrId = vaultMessage.getNameOrId(); - vaultId = vaultsUtils.decodeVaultId(vaultNameOrId); - vaultId = vaultId ?? vaultNameOrId; - // Node id - const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId()); + const { + nodeId, + vaultId, + }: { + nodeId: NodeId; + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [['nodeId'], () => validationUtils.parseNodeId(value)], + [['vaultId'], () => vaultsUtils.decodeVaultId(value) ?? value], + () => value, + ); + }, + { + nodeId: call.request.getNode()?.getNodeId(), + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); await db.withTransactionF(async (tran) => vaultManager.cloneVault(nodeId, vaultId, tran), ); @@ -54,7 +62,10 @@ function vaultsClone({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + nodesErrors.ErrorNodeGraphNodeIdNotFound, + vaultsErrors.ErrorVaultsNameConflict, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsCreate.ts b/src/client/service/vaultsCreate.ts index a739604e7..4175a7de0 100644 --- a/src/client/service/vaultsCreate.ts +++ b/src/client/service/vaultsCreate.ts @@ -7,7 +7,9 @@ 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 vaultsErrors from '../../vaults/errors'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import * as clientUtils from '../utils'; function vaultsCreate({ authenticate, @@ -37,7 +39,8 @@ function vaultsCreate({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [vaultsErrors.ErrorVaultsVaultDefined]) && + logger.error(e); return; } }; diff --git a/src/client/service/vaultsDelete.ts b/src/client/service/vaultsDelete.ts index 7a87f2da0..6aea1c1c0 100644 --- a/src/client/service/vaultsDelete.ts +++ b/src/client/service/vaultsDelete.ts @@ -1,5 +1,5 @@ import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type * as grpc from '@grpc/grpc-js'; import type { DB } from '@matrixai/db'; @@ -7,7 +7,11 @@ 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 { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as vaultsErrors from '../../vaults/errors'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsDelete({ authenticate, @@ -24,18 +28,33 @@ function vaultsDelete({ call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise => { - const vaultMessage = call.request; try { const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getNameOrId(), + }, + ); await vaultManager.destroyVault(vaultId, tran); }); response.setSuccess(true); @@ -43,7 +62,8 @@ function vaultsDelete({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [vaultsErrors.ErrorVaultsVaultUndefined]) && + logger.error(e); return; } }; diff --git a/src/client/service/vaultsList.ts b/src/client/service/vaultsList.ts index a4a618275..08646c59b 100644 --- a/src/client/service/vaultsList.ts +++ b/src/client/service/vaultsList.ts @@ -7,6 +7,7 @@ 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'; +import * as clientUtils from '../utils'; function vaultsList({ authenticate, @@ -39,7 +40,7 @@ function vaultsList({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsLog.ts b/src/client/service/vaultsLog.ts index 367dd0a1e..88873dca5 100644 --- a/src/client/service/vaultsLog.ts +++ b/src/client/service/vaultsLog.ts @@ -1,13 +1,17 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type Logger from '@matrixai/logger'; -import * as grpc from '@grpc/grpc-js'; +import type * as grpc from '@grpc/grpc-js'; import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; +import * as vaultsErrors from '../../vaults/errors'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsLog({ authenticate, @@ -27,23 +31,32 @@ function vaultsLog({ try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - // Getting the vault - const vaultsLogMessage = call.request; - const vaultMessage = vaultsLogMessage.getVault(); - if (vaultMessage == null) { - await genWritable.throw({ code: grpc.status.NOT_FOUND }); - return; - } - const nameOrId = vaultMessage.getNameOrId(); const log = await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); // Getting the log - const depth = vaultsLogMessage.getLogDepth(); - let commitId: string | undefined = vaultsLogMessage.getCommitId(); + const depth = call.request.getLogDepth(); + let commitId: string | undefined = call.request.getCommitId(); commitId = commitId ? commitId : undefined; return await vaultManager.withVaults( [vaultId], @@ -67,7 +80,10 @@ function vaultsLog({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorVaultReferenceInvalid, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsPermissionGet.ts b/src/client/service/vaultsPermissionGet.ts index 8e62be35a..d612f5b8c 100644 --- a/src/client/service/vaultsPermissionGet.ts +++ b/src/client/service/vaultsPermissionGet.ts @@ -2,8 +2,7 @@ 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 { VaultActions } from '../../vaults/types'; +import type { VaultName, VaultId, VaultActions } from '../../vaults/types'; import type ACL from '../../acl/ACL'; import type { NodeId, NodeIdEncoded } from 'nodes/types'; import type Logger from '@matrixai/logger'; @@ -11,8 +10,11 @@ import { IdInternal } from '@matrixai/id'; import * as grpcUtils from '../../grpc/utils'; import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as nodesUtils from '../../nodes/utils'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsPermissionGet({ authenticate, @@ -32,18 +34,33 @@ function vaultsPermissionGet({ ): Promise => { 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(); const [rawPermissions, vaultId] = await db.withTransactionF( async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getNameOrId(), + }, + ); // Getting permissions return [await acl.getVaultPerm(vaultId, tran), vaultId]; }, @@ -53,11 +70,9 @@ function vaultsPermissionGet({ for (const nodeId in rawPermissions) { permissionList[nodeId] = rawPermissions[nodeId].vaults[vaultId]; } - const vaultPermissionsMessage = new vaultsPB.Permissions(); - vaultPermissionsMessage.setVault(vaultMessage); + vaultPermissionsMessage.setVault(call.request); const nodeMessage = new nodesPB.Node(); - // Constructing the message for (const nodeIdString in permissionList) { const nodeId = IdInternal.fromString(nodeIdString); @@ -71,7 +86,7 @@ function vaultsPermissionGet({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsPermissionSet.ts b/src/client/service/vaultsPermissionSet.ts index f91ccd81f..335165ef7 100644 --- a/src/client/service/vaultsPermissionSet.ts +++ b/src/client/service/vaultsPermissionSet.ts @@ -1,19 +1,29 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { NodeId } from '../../nodes/types'; +import type { + VaultName, + VaultId, + VaultAction, + VaultActions, +} from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type GestaltGraph from '../../gestalts/GestaltGraph'; 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 type * as grpc from '@grpc/grpc-js'; import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as aclErrors from '../../acl/errors'; +import * as nodesErrors from '../../nodes/errors'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsPermissionSet({ authenticate, @@ -40,27 +50,37 @@ function vaultsPermissionSet({ // Checking session token const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultsPermissionsMessage = call.request; - const vaultMessage = vaultsPermissionsMessage.getVault(); - const nodeMessage = vaultsPermissionsMessage.getNode(); - if (vaultMessage == null || nodeMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } await db.withTransactionF(async (tran) => { - // Parsing VaultId - const nameOrId = vaultMessage.getNameOrId(); - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() 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)); + const { + nodeId, + vaultId, + actions, + }: { + nodeId: NodeId; + vaultId: VaultId; + actions: Array; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [['nodeId'], () => validationUtils.parseNodeId(value)], + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + [['actions'], () => value.map(validationUtils.parseVaultAction)], + () => value, + ); + }, + { + nodeId: call.request.getNode()?.getNodeId(), + vaultId: call.request.getVault()?.getNameOrId(), + actions: call.request.getVaultPermissionsList(), + }, + ); // Checking if vault exists const vaultMeta = await vaultManager.getVaultMeta(vaultId, tran); if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined(); @@ -85,7 +105,11 @@ function vaultsPermissionSet({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + aclErrors.ErrorACLNodeIdMissing, + nodesErrors.ErrorNodeGraphNodeIdNotFound, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsPermissionUnset.ts b/src/client/service/vaultsPermissionUnset.ts index 8095e21c4..9b561b173 100644 --- a/src/client/service/vaultsPermissionUnset.ts +++ b/src/client/service/vaultsPermissionUnset.ts @@ -1,16 +1,21 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { NodeId } from '../../nodes/types'; +import type { VaultName, VaultId, VaultAction } 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 type * as grpc from '@grpc/grpc-js'; import * as vaultsErrors from '../../vaults/errors'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as gestaltsErrors from '../../gestalts/errors'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsPermissionUnset({ authenticate, @@ -35,24 +40,37 @@ function vaultsPermissionUnset({ // Checking session token const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultsPermissionsMessage = call.request; - const vaultMessage = vaultsPermissionsMessage.getVault(); - const nodeMessage = vaultsPermissionsMessage.getNode(); - if (vaultMessage == null || nodeMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } 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)); + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, + tran, + ); + const { + nodeId, + vaultId, + actions, + }: { + nodeId: NodeId; + vaultId: VaultId; + actions: Array; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [['nodeId'], () => validationUtils.parseNodeId(value)], + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + [['actions'], () => value.map(validationUtils.parseVaultAction)], + () => value, + ); + }, + { + nodeId: call.request.getNode()?.getNodeId(), + vaultId: call.request.getVault()?.getNameOrId(), + actions: call.request.getVaultPermissionsList(), + }, + ); // Checking if vault exists const vaultMeta = await vaultManager.getVaultMeta(vaultId, tran); if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined(); @@ -81,7 +99,10 @@ function vaultsPermissionUnset({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsPull.ts b/src/client/service/vaultsPull.ts index f68a62903..c2e4342f6 100644 --- a/src/client/service/vaultsPull.ts +++ b/src/client/service/vaultsPull.ts @@ -1,14 +1,19 @@ 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 { VaultName, VaultId } from '../../vaults/types'; +import type { NodeId } from '../../nodes/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 type * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '../../grpc/utils'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as vaultsUtils from '../../vaults/utils'; +import * as nodesErrors from '../../nodes/errors'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsPull({ authenticate, @@ -29,39 +34,47 @@ function vaultsPull({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - - const vaultMessage = call.request.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() 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(); - } + const { + vaultId, + nodeId, + pullVaultId, + }: { + vaultId: VaultId; + nodeId: NodeId | undefined; + pullVaultId: VaultId | VaultName | undefined; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + [ + ['nodeId'], + () => (value ? validationUtils.parseNodeId(value) : undefined), + ], + [ + ['pullVaultId'], + () => vaultsUtils.decodeVaultId(value) ?? value, + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + nodeId: call.request.getNode()?.getNodeId(), + pullVaultId: call.request.getPullVault()?.getNameOrId(), + }, + ); await vaultManager.pullVault({ vaultId, pullNodeId: nodeId, - pullVaultNameOrId: pullVault, + pullVaultNameOrId: pullVaultId, tran, }); }); @@ -70,7 +83,9 @@ function vaultsPull({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + nodesErrors.ErrorNodeGraphNodeIdNotFound, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsRename.ts b/src/client/service/vaultsRename.ts index 0689b2506..9647d7ef1 100644 --- a/src/client/service/vaultsRename.ts +++ b/src/client/service/vaultsRename.ts @@ -1,13 +1,17 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type Logger from '@matrixai/logger'; -import * as grpc from '@grpc/grpc-js'; +import type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsUtils from '../../vaults/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsRename({ authenticate, @@ -28,27 +32,41 @@ function vaultsRename({ const response = new vaultsPB.Vault(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultMessage = call.request.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); const newName = call.request.getNewName() as VaultName; - await vaultManager.renameVault(vaultId, newName); + await vaultManager.renameVault(vaultId, newName, tran); response.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); }); callback(null, response); return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorVaultsVaultDefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsScan.ts b/src/client/service/vaultsScan.ts index f0392dba5..48556105e 100644 --- a/src/client/service/vaultsScan.ts +++ b/src/client/service/vaultsScan.ts @@ -7,8 +7,10 @@ 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 vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import * as nodesErrors from '../../nodes/errors'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsScan({ authenticate, @@ -56,7 +58,9 @@ function vaultsScan({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e, [ + nodesErrors.ErrorNodeGraphNodeIdNotFound, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsDelete.ts b/src/client/service/vaultsSecretsDelete.ts index 46784f9fe..86a9a77b0 100644 --- a/src/client/service/vaultsSecretsDelete.ts +++ b/src/client/service/vaultsSecretsDelete.ts @@ -1,14 +1,18 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } 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 type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsDelete({ authenticate, @@ -29,18 +33,29 @@ function vaultsSecretsDelete({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultMessage = call.request.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); const secretName = call.request.getSecretName(); await vaultManager.withVaults( [vaultId], @@ -55,7 +70,10 @@ function vaultsSecretsDelete({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorSecretsSecretUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsEdit.ts b/src/client/service/vaultsSecretsEdit.ts index 897a6dd12..374b5d9dd 100644 --- a/src/client/service/vaultsSecretsEdit.ts +++ b/src/client/service/vaultsSecretsEdit.ts @@ -1,14 +1,18 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } 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 type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsEdit({ authenticate, @@ -29,25 +33,31 @@ function vaultsSecretsEdit({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const secretMessage = call.request; - if (secretMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const vaultMessage = secretMessage.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const secretName = secretMessage.getSecretName(); - const secretContent = Buffer.from(secretMessage.getSecretContent()); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); + const secretName = call.request.getSecretName(); + const secretContent = Buffer.from(call.request.getSecretContent()); await vaultManager.withVaults( [vaultId], async (vault) => { @@ -61,7 +71,11 @@ function vaultsSecretsEdit({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorSecretsSecretUndefined, + vaultsErrors.ErrorVaultRemoteDefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsGet.ts b/src/client/service/vaultsSecretsGet.ts index cdb2a75fb..c5770db8e 100644 --- a/src/client/service/vaultsSecretsGet.ts +++ b/src/client/service/vaultsSecretsGet.ts @@ -1,14 +1,18 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } 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 type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsGet({ authenticate, @@ -29,18 +33,29 @@ function vaultsSecretsGet({ const response = new secretsPB.Secret(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultMessage = call.request.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); const secretName = call.request.getSecretName(); const secretContent = await vaultManager.withVaults( [vaultId], @@ -55,7 +70,10 @@ function vaultsSecretsGet({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorSecretsSecretUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsList.ts b/src/client/service/vaultsSecretsList.ts index 8056c7a90..b7c103cc7 100644 --- a/src/client/service/vaultsSecretsList.ts +++ b/src/client/service/vaultsSecretsList.ts @@ -1,14 +1,18 @@ import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } 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 { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsList({ authenticate, @@ -28,14 +32,29 @@ function vaultsSecretsList({ try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultMessage = call.request; - const nameOrId = vaultMessage.getNameOrId(); const secrets = await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getNameOrId(), + }, + ); return await vaultManager.withVaults( [vaultId], async (vault) => { @@ -54,7 +73,8 @@ function vaultsSecretsList({ return; } catch (e) { await genWritable.throw(e); - logger.error(e); + !clientUtils.isClientError(e, [vaultsErrors.ErrorVaultsVaultUndefined]) && + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsMkdir.ts b/src/client/service/vaultsSecretsMkdir.ts index f441207cc..eaa4e8324 100644 --- a/src/client/service/vaultsSecretsMkdir.ts +++ b/src/client/service/vaultsSecretsMkdir.ts @@ -1,14 +1,18 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } 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 type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsMkdir({ authenticate, @@ -29,24 +33,34 @@ function vaultsSecretsMkdir({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultMkdirMessge = call.request; - const vaultMessage = vaultMkdirMessge.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); await vaultManager.withVaults( [vaultId], async (vault) => { - await vaultOps.mkdir(vault, vaultMkdirMessge.getDirName(), { - recursive: vaultMkdirMessge.getRecursive(), + await vaultOps.mkdir(vault, call.request.getDirName(), { + recursive: call.request.getRecursive(), }); }, tran, @@ -57,7 +71,10 @@ function vaultsSecretsMkdir({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorVaultsRecursive, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsNew.ts b/src/client/service/vaultsSecretsNew.ts index 0a6c1920c..d89064985 100644 --- a/src/client/service/vaultsSecretsNew.ts +++ b/src/client/service/vaultsSecretsNew.ts @@ -1,14 +1,18 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } 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 type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsNew({ authenticate, @@ -29,18 +33,29 @@ function vaultsSecretsNew({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultMessage = call.request.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); const secret = call.request.getSecretName(); const content = Buffer.from(call.request.getSecretContent()); await vaultManager.withVaults( @@ -56,7 +71,10 @@ function vaultsSecretsNew({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorSecretsSecretUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsNewDir.ts b/src/client/service/vaultsSecretsNewDir.ts index daf151f58..6cc7ad0f8 100644 --- a/src/client/service/vaultsSecretsNewDir.ts +++ b/src/client/service/vaultsSecretsNewDir.ts @@ -1,15 +1,19 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } 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 type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsNewDir({ authenticate, @@ -32,18 +36,29 @@ function vaultsSecretsNewDir({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultMessage = call.request.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); const secretsPath = call.request.getSecretDirectory(); await vaultManager.withVaults( [vaultId], @@ -58,7 +73,8 @@ function vaultsSecretsNewDir({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [vaultsErrors.ErrorVaultsVaultUndefined]) && + logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsRename.ts b/src/client/service/vaultsSecretsRename.ts index fabe0512c..1b17420ff 100644 --- a/src/client/service/vaultsSecretsRename.ts +++ b/src/client/service/vaultsSecretsRename.ts @@ -1,14 +1,18 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } 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 type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsRename({ authenticate, @@ -29,24 +33,33 @@ function vaultsSecretsRename({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const secretMessage = call.request.getOldSecret(); - if (!secretMessage) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const vaultMessage = secretMessage.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getOldSecret()?.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); - const oldSecret = secretMessage.getSecretName(); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getOldSecret()?.getVault()?.getNameOrId(), + }, + ); + const oldSecret = call.request.getOldSecret()?.getSecretName(); + if (oldSecret == null) { + throw new vaultsErrors.ErrorSecretsSecretUndefined(); + } const newSecret = call.request.getNewName(); await vaultManager.withVaults( [vaultId], @@ -61,7 +74,10 @@ function vaultsSecretsRename({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorSecretsSecretUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsStat.ts b/src/client/service/vaultsSecretsStat.ts index d30b1e20f..fc173fe4b 100644 --- a/src/client/service/vaultsSecretsStat.ts +++ b/src/client/service/vaultsSecretsStat.ts @@ -1,13 +1,17 @@ import type { DB } from '@matrixai/db'; import type VaultManager from '../../vaults/VaultManager'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } from '../../vaults/types'; import type { Authenticate } from '../types'; import type Logger from '@matrixai/logger'; -import * as grpc from '@grpc/grpc-js'; +import type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsSecretsStat({ authenticate, @@ -28,18 +32,29 @@ function vaultsSecretsStat({ const response = new secretsPB.Stat(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultMessage = call.request.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); const secretName = call.request.getSecretName(); const stat = await vaultManager.withVaults( [vaultId], @@ -54,7 +69,10 @@ function vaultsSecretsStat({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorSecretsSecretUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsVersion.ts b/src/client/service/vaultsVersion.ts index 18868456b..7c755aa55 100644 --- a/src/client/service/vaultsVersion.ts +++ b/src/client/service/vaultsVersion.ts @@ -1,12 +1,16 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName } from '../../vaults/types'; +import type { VaultName, VaultId } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type Logger from '@matrixai/logger'; -import * as grpc from '@grpc/grpc-js'; +import type * as grpc from '@grpc/grpc-js'; +import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; +import { matchSync } from '../../utils'; +import * as clientUtils from '../utils'; function vaultsVersion({ authenticate, @@ -28,22 +32,31 @@ function vaultsVersion({ // Checking session token const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - const vaultsVersionMessage = call.request; - // Getting vault ID - const vaultMessage = vaultsVersionMessage.getVault(); - if (vaultMessage == null) { - callback({ code: grpc.status.NOT_FOUND }, null); - return; - } - const nameOrId = vaultMessage.getNameOrId(); await db.withTransactionF(async (tran) => { - let vaultId = await vaultManager.getVaultId( - nameOrId as VaultName, + const vaultIdFromName = await vaultManager.getVaultId( + call.request.getVault()?.getNameOrId() as VaultName, tran, ); - vaultId = vaultId ?? validationUtils.parseVaultId(nameOrId); + const { + vaultId, + }: { + vaultId: VaultId; + } = validateSync( + (keyPath, value) => { + return matchSync(keyPath)( + [ + ['vaultId'], + () => vaultIdFromName ?? validationUtils.parseVaultId(value), + ], + () => value, + ); + }, + { + vaultId: call.request.getVault()?.getNameOrId(), + }, + ); // Doing the deed - const versionId = vaultsVersionMessage.getVersionId(); + const versionId = call.request.getVersionId(); const [latestOid, currentVersionId] = await vaultManager.withVaults( [vaultId], async (vault) => { @@ -65,7 +78,11 @@ function vaultsVersion({ return; } catch (e) { callback(grpcUtils.fromError(e)); - logger.error(e); + !clientUtils.isClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + vaultsErrors.ErrorVaultReferenceInvalid, + vaultsErrors.ErrorVaultReferenceMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/utils/utils.ts b/src/client/utils/utils.ts index d49173a6f..b77ac0e76 100644 --- a/src/client/utils/utils.ts +++ b/src/client/utils/utils.ts @@ -3,6 +3,7 @@ import type { Interceptor, InterceptorOptions, } from '@grpc/grpc-js/build/src/client-interceptors'; +import type { Class } from '@matrixai/errors'; import type KeyManager from '../../keys/KeyManager'; import type Session from '../../sessions/Session'; import type SessionManager from '../../sessions/SessionManager'; @@ -10,8 +11,20 @@ import type { SessionToken } from '../../sessions/types'; import type { Authenticate } from '../types'; import * as base64 from 'multiformats/bases/base64'; import * as grpc from '@grpc/grpc-js'; +import * as validationErrors from '../../validation/errors'; import * as clientErrors from '../errors'; +/** + * Array of errors that are always considered to be "client errors" + * (4xx errors in HTTP) in the context of the client service + */ +const defaultClientErrors: Array> = [ + validationErrors.ErrorValidation, + clientErrors.ErrorClientAuthMissing, + clientErrors.ErrorClientAuthFormat, + clientErrors.ErrorClientAuthDenied, +]; + /** * Session interceptor middleware for authenticatio * Session token is read at the beginning of every call @@ -133,10 +146,34 @@ function decodeAuthToSession( return auth.substring(7) as SessionToken; } +/** + * Checks whether an error is a "client error" (4xx errors in HTTP) + * Used by the service handlers since client errors should not be + * reported on the server side + * Additional errors that are considered to be client errors in the + * context of a given handler can be supplied in the `extraClientErrors` + * argument + */ +function isClientError( + e: Error, + extraClientErrors?: Array>, +): boolean { + for (const error of defaultClientErrors) { + if (e instanceof error) return true; + } + if (extraClientErrors) { + for (const error of extraClientErrors) { + if (e instanceof error) return true; + } + } + return false; +} + export { sessionInterceptor, authenticator, encodeAuthFromPassword, encodeAuthFromSession, decodeAuthToSession, + isClientError, }; From 7375e1dbbd4e18d35606f6095b97f4a13ae76a0b Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 3 Jun 2022 15:19:43 +1000 Subject: [PATCH 69/74] feat: updated `Opaque` usage --- src/types.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 8fba1fc08..fedc06923 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,7 +10,8 @@ type POJO = { [key: string]: any }; * Opaque types are wrappers of existing types * that require smart constructors */ -type Opaque = T & { __TYPE__: K }; +type Opaque = T & { readonly [brand]: K }; +declare const brand: unique symbol; /** * Non-empty array From a244c30b55af321c2bcdafe687ccfcfb14dcd47a Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 3 Jun 2022 15:42:49 +1000 Subject: [PATCH 70/74] feat: `promisify` utility now preserves typing info --- src/bin/polykey-agent.ts | 2 +- src/types.ts | 9 +++++++++ src/utils/utils.ts | 28 ++++++++++++++++++++++------ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/bin/polykey-agent.ts b/src/bin/polykey-agent.ts index de65ebc86..b9476b514 100644 --- a/src/bin/polykey-agent.ts +++ b/src/bin/polykey-agent.ts @@ -37,7 +37,7 @@ const logger = new Logger('polykey', undefined, [new StreamHandler()]); */ async function main(_argv = process.argv): Promise { const exitHandlers = new binUtils.ExitHandlers(); - const processSend = promisify(process.send!.bind(process)); + const processSend = promisify(process.send!.bind(process)); const { p: messageInP, resolveP: resolveMessageInP } = promise(); process.once('message', (data: AgentChildProcessInput) => { diff --git a/src/types.ts b/src/types.ts index fedc06923..161181b8d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -13,6 +13,14 @@ type POJO = { [key: string]: any }; type Opaque = T & { readonly [brand]: K }; declare const brand: unique symbol; +/** + * Generic callback + */ +type Callback

= [], R = any, E extends Error = Error> = { + (e: E, ...params: Partial

): R; + (e?: null | undefined, ...params: P): R; +}; + /** * Non-empty array */ @@ -81,6 +89,7 @@ type FileHandle = fs.promises.FileHandle; export type { POJO, Opaque, + Callback, NonEmptyArray, AbstractConstructorParameters, Initial, diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 6b4ca4759..4d837ecbf 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,4 +1,4 @@ -import type { FileSystem, Timer } from '../types'; +import type { FileSystem, Timer, Callback } from '../types'; import os from 'os'; import process from 'process'; import path from 'path'; @@ -138,18 +138,34 @@ async function poll( /** * Convert callback-style to promise-style + * If this is applied to overloaded function + * it will only choose one of the function signatures to use */ -function promisify(f): (...args: any[]) => Promise { - return function (...args): Promise { +function promisify< + T extends Array, + P extends Array, + R extends T extends [] ? void : T extends [unknown] ? T[0] : T, +>( + f: (...args: [...params: P, callback: Callback]) => unknown, +): (...params: P) => Promise { + // Uses a regular function so that `this` can be bound + return function (...params: P): Promise { return new Promise((resolve, reject) => { const callback = (error, ...values) => { if (error != null) { return reject(error); } - return resolve(values.length === 1 ? values[0] : values); + if (values.length === 0) { + (resolve as () => void)(); + } else if (values.length === 1) { + resolve(values[0] as R); + } else { + resolve(values as R); + } + return; }; - args.push(callback); - f.apply(this, args); + params.push(callback); + f.apply(this, params); }); }; } From bb50d71c9b96fc6fb754fa94286567efe0672804 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 6 Jun 2022 12:17:40 +1000 Subject: [PATCH 71/74] fix: bug fixes in vaults service handlers --- src/agent/service/vaultsGitPackGet.ts | 7 ++++--- src/client/service/vaultsClone.ts | 18 ++++++++++-------- src/client/service/vaultsPull.ts | 16 +++++++++------- tests/bin/vaults/vaults.test.ts | 4 ++-- tests/vaults/VaultManager.test.ts | 3 ++- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/agent/service/vaultsGitPackGet.ts b/src/agent/service/vaultsGitPackGet.ts index e17cad29f..276cec84f 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -56,9 +56,10 @@ function vaultsGitPackGet({ } const nodeId = connectionInfo.remoteNodeId; const nodeIdEncoded = nodesUtils.encodeNodeId(nodeId); + const nameOrId = meta.get('vaultNameOrId').pop()!.toString(); await db.withTransactionF(async (tran) => { const vaultIdFromName = await vaultManager.getVaultId( - meta.get('vaultNameOrId').pop()!.toString() as VaultName, + nameOrId as VaultName, tran, ); const { @@ -79,8 +80,8 @@ function vaultsGitPackGet({ ); }, { - vaultId: meta.get('vaultNameOrId').pop(), - actionType: meta.get('vaultAction').pop(), + vaultId: nameOrId, + actionType: meta.get('vaultAction').pop()!.toString(), }, ); // Checking permissions diff --git a/src/client/service/vaultsClone.ts b/src/client/service/vaultsClone.ts index 4e931e551..fdefe5697 100644 --- a/src/client/service/vaultsClone.ts +++ b/src/client/service/vaultsClone.ts @@ -1,7 +1,7 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; -import type { VaultId } from '../../vaults/types'; +import type { VaultName, VaultId } from '../../vaults/types'; import type { NodeId } from '../../nodes/types'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; import type Logger from '@matrixai/logger'; @@ -35,28 +35,30 @@ function vaultsClone({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); + // Node id const { nodeId, - vaultId, }: { nodeId: NodeId; - vaultId: VaultId; } = validateSync( (keyPath, value) => { return matchSync(keyPath)( [['nodeId'], () => validationUtils.parseNodeId(value)], - [['vaultId'], () => vaultsUtils.decodeVaultId(value) ?? value], () => value, ); }, { nodeId: call.request.getNode()?.getNodeId(), - vaultId: call.request.getVault()?.getNameOrId(), }, ); - await db.withTransactionF(async (tran) => - vaultManager.cloneVault(nodeId, vaultId, tran), - ); + // Vault id + let vaultId; + const vaultNameOrId = call.request.getVault()?.getNameOrId(); + vaultId = vaultsUtils.decodeVaultId(vaultNameOrId); + vaultId = vaultId ?? vaultNameOrId; + await db.withTransactionF(async (tran) => { + await vaultManager.cloneVault(nodeId, vaultId, tran); + }); response.setSuccess(true); callback(null, response); return; diff --git a/src/client/service/vaultsPull.ts b/src/client/service/vaultsPull.ts index c2e4342f6..6f7d19106 100644 --- a/src/client/service/vaultsPull.ts +++ b/src/client/service/vaultsPull.ts @@ -34,6 +34,15 @@ function vaultsPull({ const response = new utilsPB.StatusMessage(); const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); + let pullVaultId; + const pullVaultMessage = call.request.getPullVault(); + if (pullVaultMessage == null) { + pullVaultId = null; + } else { + pullVaultId = vaultsUtils.decodeVaultId(pullVaultMessage.getNameOrId()); + pullVaultId = pullVaultId ?? pullVaultMessage.getNameOrId(); + if (pullVaultId == null) pullVaultId = pullVaultMessage.getNameOrId(); + } await db.withTransactionF(async (tran) => { const vaultIdFromName = await vaultManager.getVaultId( call.request.getVault()?.getNameOrId() as VaultName, @@ -42,11 +51,9 @@ function vaultsPull({ const { vaultId, nodeId, - pullVaultId, }: { vaultId: VaultId; nodeId: NodeId | undefined; - pullVaultId: VaultId | VaultName | undefined; } = validateSync( (keyPath, value) => { return matchSync(keyPath)( @@ -58,17 +65,12 @@ function vaultsPull({ ['nodeId'], () => (value ? validationUtils.parseNodeId(value) : undefined), ], - [ - ['pullVaultId'], - () => vaultsUtils.decodeVaultId(value) ?? value, - ], () => value, ); }, { vaultId: call.request.getVault()?.getNameOrId(), nodeId: call.request.getNode()?.getNodeId(), - pullVaultId: call.request.getPullVault()?.getNameOrId(), }, ); await vaultManager.pullVault({ diff --git a/tests/bin/vaults/vaults.test.ts b/tests/bin/vaults/vaults.test.ts index 52b5f4e4c..a8e6fa3df 100644 --- a/tests/bin/vaults/vaults.test.ts +++ b/tests/bin/vaults/vaults.test.ts @@ -342,8 +342,8 @@ describe('CLI vaults', () => { targetNodeIdEncoded, ]; result = await testBinUtils.pkStdio([...command], {}, dataDir); - expect(result.exitCode).toBe(sysexits.USAGE); - expect(result.stderr).toContain('ErrorVaultsVaultUndefined'); + expect(result.exitCode).toBe(sysexits.DATAERR); + expect(result.stderr).toContain('ErrorValidation'); command = [ 'vaults', diff --git a/tests/vaults/VaultManager.test.ts b/tests/vaults/VaultManager.test.ts index e4ed618aa..c62824b1d 100644 --- a/tests/vaults/VaultManager.test.ts +++ b/tests/vaults/VaultManager.test.ts @@ -23,6 +23,7 @@ import KeyManager from '@/keys/KeyManager'; import PolykeyAgent from '@/PolykeyAgent'; import VaultManager from '@/vaults/VaultManager'; import * as vaultsErrors from '@/vaults/errors'; +import * as validationErrors from '@/validation/errors'; import NodeGraph from '@/nodes/NodeGraph'; import * as nodesUtils from '@/nodes/utils'; import Proxy from '@/network/Proxy'; @@ -743,7 +744,7 @@ describe('VaultManager', () => { remoteKeynode1Id, 'not-existing' as VaultName, ), - vaultsErrors.ErrorVaultsVaultUndefined, + validationErrors.ErrorValidation, ); } finally { await vaultManager?.stop(); From fe0070b42e2760f80899541334d5a6f19c9b8d24 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 6 Jun 2022 12:24:56 +1000 Subject: [PATCH 72/74] style: lint fix --- src/client/service/vaultsClone.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/service/vaultsClone.ts b/src/client/service/vaultsClone.ts index fdefe5697..86129010d 100644 --- a/src/client/service/vaultsClone.ts +++ b/src/client/service/vaultsClone.ts @@ -1,7 +1,6 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; -import type { VaultName, VaultId } from '../../vaults/types'; import type { NodeId } from '../../nodes/types'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; import type Logger from '@matrixai/logger'; From 26fd955afd3fe9323385e9cf85b2a303668792cc Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 6 Jun 2022 14:53:12 +1000 Subject: [PATCH 73/74] fix: service handlers check for client error chains Sometimes an error is only considered a client error when part of the chain of another error (for example ErrorPolykeyRemote) so it is now possible to specify this array. #304 --- src/agent/service/nodesChainDataGet.ts | 2 +- .../service/nodesClosestLocalNodesGet.ts | 2 +- src/agent/service/nodesCrossSignClaim.ts | 2 +- .../service/nodesHolePunchMessageSend.ts | 2 +- src/agent/service/notificationsSend.ts | 2 +- src/agent/service/vaultsGitInfoGet.ts | 17 +++--- src/agent/service/vaultsGitPackGet.ts | 15 ++--- src/agent/service/vaultsScan.ts | 2 +- src/agent/types.ts | 10 +++- src/agent/utils.ts | 56 +++++++++++++++---- src/client/service/agentLockAll.ts | 2 +- src/client/service/agentStatus.ts | 2 +- src/client/service/agentStop.ts | 2 +- src/client/service/agentUnlock.ts | 2 +- .../service/gestaltsActionsGetByIdentity.ts | 2 +- .../service/gestaltsActionsGetByNode.ts | 2 +- .../service/gestaltsActionsSetByIdentity.ts | 2 +- .../service/gestaltsActionsSetByNode.ts | 2 +- .../service/gestaltsActionsUnsetByIdentity.ts | 2 +- .../service/gestaltsActionsUnsetByNode.ts | 2 +- .../service/gestaltsDiscoveryByIdentity.ts | 2 +- src/client/service/gestaltsDiscoveryByNode.ts | 2 +- .../service/gestaltsGestaltGetByIdentity.ts | 2 +- .../service/gestaltsGestaltGetByNode.ts | 2 +- src/client/service/gestaltsGestaltList.ts | 2 +- .../service/gestaltsGestaltTrustByIdentity.ts | 2 +- .../service/gestaltsGestaltTrustByNode.ts | 2 +- src/client/service/identitiesAuthenticate.ts | 5 +- .../service/identitiesAuthenticatedGet.ts | 2 +- src/client/service/identitiesClaim.ts | 2 +- .../service/identitiesInfoConnectedGet.ts | 2 +- src/client/service/identitiesInfoGet.ts | 2 +- src/client/service/identitiesProvidersList.ts | 2 +- src/client/service/identitiesTokenDelete.ts | 2 +- src/client/service/identitiesTokenGet.ts | 2 +- src/client/service/identitiesTokenPut.ts | 2 +- src/client/service/keysCertsChainGet.ts | 2 +- src/client/service/keysCertsGet.ts | 2 +- src/client/service/keysDecrypt.ts | 2 +- src/client/service/keysEncrypt.ts | 2 +- src/client/service/keysKeyPairRenew.ts | 2 +- src/client/service/keysKeyPairReset.ts | 2 +- src/client/service/keysKeyPairRoot.ts | 2 +- src/client/service/keysPasswordChange.ts | 2 +- src/client/service/keysSign.ts | 2 +- src/client/service/keysVerify.ts | 2 +- src/client/service/nodesAdd.ts | 2 +- src/client/service/nodesClaim.ts | 2 +- src/client/service/nodesFind.ts | 2 +- src/client/service/nodesPing.ts | 2 +- src/client/service/notificationsClear.ts | 2 +- src/client/service/notificationsRead.ts | 2 +- src/client/service/notificationsSend.ts | 2 +- src/client/service/vaultsClone.ts | 4 +- src/client/service/vaultsCreate.ts | 5 +- src/client/service/vaultsDelete.ts | 35 ++++-------- src/client/service/vaultsList.ts | 2 +- src/client/service/vaultsLog.ts | 32 +++-------- src/client/service/vaultsPermissionGet.ts | 35 ++++-------- src/client/service/vaultsPermissionSet.ts | 22 +++----- src/client/service/vaultsPermissionUnset.ts | 18 +++--- src/client/service/vaultsPull.ts | 21 ++++--- src/client/service/vaultsRename.ts | 31 +++------- src/client/service/vaultsScan.ts | 2 +- src/client/service/vaultsSecretsDelete.ts | 32 +++-------- src/client/service/vaultsSecretsEdit.ts | 32 +++-------- src/client/service/vaultsSecretsGet.ts | 32 +++-------- src/client/service/vaultsSecretsList.ts | 35 ++++-------- src/client/service/vaultsSecretsMkdir.ts | 32 +++-------- src/client/service/vaultsSecretsNew.ts | 32 +++-------- src/client/service/vaultsSecretsNewDir.ts | 35 ++++-------- src/client/service/vaultsSecretsRename.ts | 36 ++++-------- src/client/service/vaultsSecretsStat.ts | 32 +++-------- src/client/service/vaultsVersion.ts | 32 +++-------- src/client/types.ts | 8 ++- src/client/utils/utils.ts | 52 ++++++++++++++--- tests/bin/vaults/vaults.test.ts | 4 +- tests/vaults/VaultManager.test.ts | 3 +- 78 files changed, 345 insertions(+), 458 deletions(-) diff --git a/src/agent/service/nodesChainDataGet.ts b/src/agent/service/nodesChainDataGet.ts index 0e09ff35f..e0f838b33 100644 --- a/src/agent/service/nodesChainDataGet.ts +++ b/src/agent/service/nodesChainDataGet.ts @@ -51,7 +51,7 @@ function nodesChainDataGet({ return; } catch (e) { callback(grpcUtils.fromError(e, true)); - !agentUtils.isClientError(e) && logger.error(e); + !agentUtils.isAgentClientError(e) && logger.error(e); return; } }; diff --git a/src/agent/service/nodesClosestLocalNodesGet.ts b/src/agent/service/nodesClosestLocalNodesGet.ts index e28fbd191..5c2c0e204 100644 --- a/src/agent/service/nodesClosestLocalNodesGet.ts +++ b/src/agent/service/nodesClosestLocalNodesGet.ts @@ -67,7 +67,7 @@ function nodesClosestLocalNodesGet({ return; } catch (e) { callback(grpcUtils.fromError(e, true)); - !agentUtils.isClientError(e) && logger.error(e); + !agentUtils.isAgentClientError(e) && logger.error(e); return; } }; diff --git a/src/agent/service/nodesCrossSignClaim.ts b/src/agent/service/nodesCrossSignClaim.ts index 63b6304c9..20d5ac575 100644 --- a/src/agent/service/nodesCrossSignClaim.ts +++ b/src/agent/service/nodesCrossSignClaim.ts @@ -173,7 +173,7 @@ function nodesCrossSignClaim({ }); } catch (e) { await genClaims.throw(e); - !agentUtils.isClientError(e, [ + !agentUtils.isAgentClientError(e, [ claimsErrors.ErrorEmptyStream, claimsErrors.ErrorUndefinedSinglySignedClaim, claimsErrors.ErrorUndefinedSignature, diff --git a/src/agent/service/nodesHolePunchMessageSend.ts b/src/agent/service/nodesHolePunchMessageSend.ts index 1ec86a35c..088787264 100644 --- a/src/agent/service/nodesHolePunchMessageSend.ts +++ b/src/agent/service/nodesHolePunchMessageSend.ts @@ -74,7 +74,7 @@ function nodesHolePunchMessageSend({ return; } catch (e) { callback(grpcUtils.fromError(e, true)); - !agentUtils.isClientError(e) && logger.error(e); + !agentUtils.isAgentClientError(e) && logger.error(e); return; } }; diff --git a/src/agent/service/notificationsSend.ts b/src/agent/service/notificationsSend.ts index 6108cbe74..eb336243c 100644 --- a/src/agent/service/notificationsSend.ts +++ b/src/agent/service/notificationsSend.ts @@ -36,7 +36,7 @@ function notificationsSend({ return; } catch (e) { callback(grpcUtils.fromError(e, true)); - !agentUtils.isClientError(e, [ + !agentUtils.isAgentClientError(e, [ notificationsErrors.ErrorNotificationsInvalidType, notificationsErrors.ErrorNotificationsValidationFailed, notificationsErrors.ErrorNotificationsParse, diff --git a/src/agent/service/vaultsGitInfoGet.ts b/src/agent/service/vaultsGitInfoGet.ts index aecdde37e..7fe9831ff 100644 --- a/src/agent/service/vaultsGitInfoGet.ts +++ b/src/agent/service/vaultsGitInfoGet.ts @@ -1,5 +1,5 @@ import type { DB } from '@matrixai/db'; -import type { VaultName, VaultId, VaultAction } from '../../vaults/types'; +import type { VaultName, VaultAction } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type ACL from '../../acl/ACL'; import type { ConnectionInfoGet } from '../../agent/types'; @@ -39,25 +39,24 @@ function vaultsGitInfoGet({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const { - vaultId, actionType, }: { - vaultId: VaultId; actionType: VaultAction; } = validateSync( (keyPath, value) => { return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], [['actionType'], () => validationUtils.parseVaultAction(value)], () => value, ); }, { - vaultId: call.request.getVault()?.getNameOrId(), actionType: call.request.getAction(), }, ); @@ -108,7 +107,7 @@ function vaultsGitInfoGet({ return; } catch (e) { await genWritable.throw(e); - !agentUtils.isClientError(e, [ + !agentUtils.isAgentClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, agentErrors.ErrorConnectionInfoMissing, vaultsErrors.ErrorVaultsPermissionDenied, diff --git a/src/agent/service/vaultsGitPackGet.ts b/src/agent/service/vaultsGitPackGet.ts index 276cec84f..50db9da28 100644 --- a/src/agent/service/vaultsGitPackGet.ts +++ b/src/agent/service/vaultsGitPackGet.ts @@ -1,6 +1,6 @@ import type * as grpc from '@grpc/grpc-js'; import type { DB } from '@matrixai/db'; -import type { VaultName, VaultId, VaultAction } from '../../vaults/types'; +import type { VaultName, VaultAction } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type { ConnectionInfoGet } from '../../agent/types'; import type ACL from '../../acl/ACL'; @@ -62,25 +62,22 @@ function vaultsGitPackGet({ nameOrId as VaultName, tran, ); + const vaultId = vaultIdFromName ?? vaultsUtils.decodeVaultId(nameOrId); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const { - vaultId, actionType, }: { - vaultId: VaultId; actionType: VaultAction; } = validateSync( (keyPath, value) => { return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], [['actionType'], () => validationUtils.parseVaultAction(value)], () => value, ); }, { - vaultId: nameOrId, actionType: meta.get('vaultAction').pop()!.toString(), }, ); @@ -123,7 +120,7 @@ function vaultsGitPackGet({ return; } catch (e) { await genDuplex.throw(e); - !agentUtils.isClientError(e, [ + !agentUtils.isAgentClientError(e, [ agentErrors.ErrorConnectionInfoMissing, vaultsErrors.ErrorVaultsPermissionDenied, vaultsErrors.ErrorVaultsVaultUndefined, diff --git a/src/agent/service/vaultsScan.ts b/src/agent/service/vaultsScan.ts index 42e6ca8eb..f1a94c2a9 100644 --- a/src/agent/service/vaultsScan.ts +++ b/src/agent/service/vaultsScan.ts @@ -53,7 +53,7 @@ function vaultsScan({ return; } catch (e) { await genWritable.throw(e); - !agentUtils.isClientError(e, [ + !agentUtils.isAgentClientError(e, [ agentErrors.ErrorConnectionInfoMissing, vaultsErrors.ErrorVaultsPermissionDenied, ]) && logger.error(e); diff --git a/src/agent/types.ts b/src/agent/types.ts index ced17bbf1..b6d0e0259 100644 --- a/src/agent/types.ts +++ b/src/agent/types.ts @@ -1,8 +1,14 @@ -import type { ConnectionInfo } from 'network/types'; import type { ServerSurfaceCall } from '@grpc/grpc-js/build/src/server-call'; +import type { Class } from '@matrixai/errors'; +import type { ConnectionInfo } from '../network/types'; +import type ErrorPolykey from '../ErrorPolykey'; type ConnectionInfoGet = ( call: ServerSurfaceCall, ) => ConnectionInfo | undefined; -export type { ConnectionInfoGet }; +type AgentClientErrors = Array< + Class> | Array>> +>; + +export type { ConnectionInfoGet, AgentClientErrors }; diff --git a/src/agent/utils.ts b/src/agent/utils.ts index 94b7d97d5..48f9ff59f 100644 --- a/src/agent/utils.ts +++ b/src/agent/utils.ts @@ -1,15 +1,15 @@ import type { ServerSurfaceCall } from '@grpc/grpc-js/build/src/server-call'; -import type { Class } from '@matrixai/errors'; -import type { Host, Port } from 'network/types'; -import type Proxy from 'network/Proxy'; -import type { ConnectionInfoGet } from './types'; +import type ErrorPolykey from '../ErrorPolykey'; +import type { Host, Port } from '../network/types'; +import type Proxy from '../network/Proxy'; +import type { ConnectionInfoGet, AgentClientErrors } from './types'; import * as validationErrors from '../validation/errors'; /** * Array of errors that are always considered to be "client errors" * (4xx errors in HTTP) in the context of the agent service */ -const defaultClientErrors: Array> = [ +const defaultClientErrors: AgentClientErrors = [ validationErrors.ErrorValidation, ]; @@ -33,19 +33,53 @@ function connectionInfoGetter(proxy: Proxy): ConnectionInfoGet { * context of a given handler can be supplied in the `extraClientErrors` * argument */ -function isClientError( - e: Error, - extraClientErrors?: Array>, +function isAgentClientError( + thrownError: ErrorPolykey, + extraClientErrors?: AgentClientErrors, ): boolean { for (const error of defaultClientErrors) { - if (e instanceof error) return true; + if (Array.isArray(error)) { + let e = thrownError; + let matches = true; + for (const eType of error) { + if (e == null) { + matches = false; + break; + } + if (!(e instanceof eType)) { + matches = false; + break; + } + e = e.cause; + } + if (matches) return true; + } else if (thrownError instanceof error) { + return true; + } } if (extraClientErrors) { for (const error of extraClientErrors) { - if (e instanceof error) return true; + if (Array.isArray(error)) { + let e = thrownError; + let matches = true; + for (const eType of error) { + if (e == null) { + matches = false; + break; + } + if (!(e instanceof eType)) { + matches = false; + break; + } + e = e.cause; + } + if (matches) return true; + } else if (thrownError instanceof error) { + return true; + } } } return false; } -export { connectionInfoGetter, isClientError }; +export { connectionInfoGetter, isAgentClientError }; diff --git a/src/client/service/agentLockAll.ts b/src/client/service/agentLockAll.ts index 90ad0a93a..29e64bcad 100644 --- a/src/client/service/agentLockAll.ts +++ b/src/client/service/agentLockAll.ts @@ -33,7 +33,7 @@ function agentLockAll({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/agentStatus.ts b/src/client/service/agentStatus.ts index 52d14144a..110555cf8 100644 --- a/src/client/service/agentStatus.ts +++ b/src/client/service/agentStatus.ts @@ -50,7 +50,7 @@ function agentStatus({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/agentStop.ts b/src/client/service/agentStop.ts index a745887e5..f88885f09 100644 --- a/src/client/service/agentStop.ts +++ b/src/client/service/agentStop.ts @@ -33,7 +33,7 @@ function agentStop({ callback(null, response); } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(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 1f726792d..5147e2718 100644 --- a/src/client/service/agentUnlock.ts +++ b/src/client/service/agentUnlock.ts @@ -24,7 +24,7 @@ function agentUnlock({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsGetByIdentity.ts b/src/client/service/gestaltsActionsGetByIdentity.ts index bd0d8ba04..ef45d57e7 100644 --- a/src/client/service/gestaltsActionsGetByIdentity.ts +++ b/src/client/service/gestaltsActionsGetByIdentity.ts @@ -63,7 +63,7 @@ function gestaltsActionsGetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsGetByNode.ts b/src/client/service/gestaltsActionsGetByNode.ts index 11187384b..b5652d3bb 100644 --- a/src/client/service/gestaltsActionsGetByNode.ts +++ b/src/client/service/gestaltsActionsGetByNode.ts @@ -57,7 +57,7 @@ function gestaltsActionsGetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsActionsSetByIdentity.ts b/src/client/service/gestaltsActionsSetByIdentity.ts index 3776bbebb..0628b2a98 100644 --- a/src/client/service/gestaltsActionsSetByIdentity.ts +++ b/src/client/service/gestaltsActionsSetByIdentity.ts @@ -68,7 +68,7 @@ function gestaltsActionsSetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, ]) && logger.error(e); diff --git a/src/client/service/gestaltsActionsSetByNode.ts b/src/client/service/gestaltsActionsSetByNode.ts index 91cef278f..2aa9a7050 100644 --- a/src/client/service/gestaltsActionsSetByNode.ts +++ b/src/client/service/gestaltsActionsSetByNode.ts @@ -54,7 +54,7 @@ function gestaltsActionsSetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, ]) && logger.error(e); return; diff --git a/src/client/service/gestaltsActionsUnsetByIdentity.ts b/src/client/service/gestaltsActionsUnsetByIdentity.ts index 1b20a5610..88745bc64 100644 --- a/src/client/service/gestaltsActionsUnsetByIdentity.ts +++ b/src/client/service/gestaltsActionsUnsetByIdentity.ts @@ -68,7 +68,7 @@ function gestaltsActionsUnsetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, ]) && logger.error(e); diff --git a/src/client/service/gestaltsActionsUnsetByNode.ts b/src/client/service/gestaltsActionsUnsetByNode.ts index 1f06d2c64..d7a62d68a 100644 --- a/src/client/service/gestaltsActionsUnsetByNode.ts +++ b/src/client/service/gestaltsActionsUnsetByNode.ts @@ -54,7 +54,7 @@ function gestaltsActionsUnsetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, ]) && logger.error(e); return; diff --git a/src/client/service/gestaltsDiscoveryByIdentity.ts b/src/client/service/gestaltsDiscoveryByIdentity.ts index b63bb83bf..37efbf7d3 100644 --- a/src/client/service/gestaltsDiscoveryByIdentity.ts +++ b/src/client/service/gestaltsDiscoveryByIdentity.ts @@ -52,7 +52,7 @@ function gestaltsDiscoveryByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsDiscoveryByNode.ts b/src/client/service/gestaltsDiscoveryByNode.ts index b37bd777c..0c8d1ea4c 100644 --- a/src/client/service/gestaltsDiscoveryByNode.ts +++ b/src/client/service/gestaltsDiscoveryByNode.ts @@ -48,7 +48,7 @@ function gestaltsDiscoveryByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltGetByIdentity.ts b/src/client/service/gestaltsGestaltGetByIdentity.ts index 9396c3d6d..81e3ffc54 100644 --- a/src/client/service/gestaltsGestaltGetByIdentity.ts +++ b/src/client/service/gestaltsGestaltGetByIdentity.ts @@ -60,7 +60,7 @@ function gestaltsGestaltGetByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltGetByNode.ts b/src/client/service/gestaltsGestaltGetByNode.ts index 2fbbb8447..fb3e63f56 100644 --- a/src/client/service/gestaltsGestaltGetByNode.ts +++ b/src/client/service/gestaltsGestaltGetByNode.ts @@ -56,7 +56,7 @@ function gestaltsGestaltGetByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltList.ts b/src/client/service/gestaltsGestaltList.ts index cbe2e0027..7b4725892 100644 --- a/src/client/service/gestaltsGestaltList.ts +++ b/src/client/service/gestaltsGestaltList.ts @@ -40,7 +40,7 @@ function gestaltsGestaltList({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/gestaltsGestaltTrustByIdentity.ts b/src/client/service/gestaltsGestaltTrustByIdentity.ts index 9fc7c4911..36a0aa982 100644 --- a/src/client/service/gestaltsGestaltTrustByIdentity.ts +++ b/src/client/service/gestaltsGestaltTrustByIdentity.ts @@ -84,7 +84,7 @@ function gestaltsGestaltTrustByIdentity({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ gestaltsErrors.ErrorGestaltsGraphIdentityIdMissing, gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, ]) && logger.error(e); diff --git a/src/client/service/gestaltsGestaltTrustByNode.ts b/src/client/service/gestaltsGestaltTrustByNode.ts index 9be7fa628..8fa7299a0 100644 --- a/src/client/service/gestaltsGestaltTrustByNode.ts +++ b/src/client/service/gestaltsGestaltTrustByNode.ts @@ -71,7 +71,7 @@ function gestaltsGestaltTrustByNode({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, ]) && logger.error(e); return; diff --git a/src/client/service/identitiesAuthenticate.ts b/src/client/service/identitiesAuthenticate.ts index 9aa0927e0..d9c216c6c 100644 --- a/src/client/service/identitiesAuthenticate.ts +++ b/src/client/service/identitiesAuthenticate.ts @@ -75,8 +75,9 @@ function identitiesAuthenticate({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e, [identitiesErrors.ErrorProviderMissing]) && - logger.error(e); + !clientUtils.isClientClientError(e, [ + identitiesErrors.ErrorProviderMissing, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesAuthenticatedGet.ts b/src/client/service/identitiesAuthenticatedGet.ts index 64d0d7232..3ab4cc941 100644 --- a/src/client/service/identitiesAuthenticatedGet.ts +++ b/src/client/service/identitiesAuthenticatedGet.ts @@ -64,7 +64,7 @@ function identitiesAuthenticatedGet({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesClaim.ts b/src/client/service/identitiesClaim.ts index 884a5ca1c..de5e1df57 100644 --- a/src/client/service/identitiesClaim.ts +++ b/src/client/service/identitiesClaim.ts @@ -93,7 +93,7 @@ function identitiesClaim({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ identitiesErrors.ErrorProviderMissing, identitiesErrors.ErrorProviderUnauthenticated, ]) && logger.error(e); diff --git a/src/client/service/identitiesInfoConnectedGet.ts b/src/client/service/identitiesInfoConnectedGet.ts index 7ac96810c..63d681700 100644 --- a/src/client/service/identitiesInfoConnectedGet.ts +++ b/src/client/service/identitiesInfoConnectedGet.ts @@ -120,7 +120,7 @@ function identitiesInfoConnectedGet({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ identitiesErrors.ErrorProviderMissing, identitiesErrors.ErrorProviderUnauthenticated, identitiesErrors.ErrorProviderUnimplemented, diff --git a/src/client/service/identitiesInfoGet.ts b/src/client/service/identitiesInfoGet.ts index bd29cf2f3..e8df1153b 100644 --- a/src/client/service/identitiesInfoGet.ts +++ b/src/client/service/identitiesInfoGet.ts @@ -113,7 +113,7 @@ function identitiesInfoGet({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ identitiesErrors.ErrorProviderMissing, identitiesErrors.ErrorProviderUnauthenticated, ]) && logger.error(e); diff --git a/src/client/service/identitiesProvidersList.ts b/src/client/service/identitiesProvidersList.ts index cd451d2f9..70cbc9ccd 100644 --- a/src/client/service/identitiesProvidersList.ts +++ b/src/client/service/identitiesProvidersList.ts @@ -30,7 +30,7 @@ function identitiesProvidersList({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenDelete.ts b/src/client/service/identitiesTokenDelete.ts index 9abe9d624..779ffea47 100644 --- a/src/client/service/identitiesTokenDelete.ts +++ b/src/client/service/identitiesTokenDelete.ts @@ -57,7 +57,7 @@ function identitiesTokenDelete({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenGet.ts b/src/client/service/identitiesTokenGet.ts index 193cf2553..5ca76f585 100644 --- a/src/client/service/identitiesTokenGet.ts +++ b/src/client/service/identitiesTokenGet.ts @@ -57,7 +57,7 @@ function identitiesTokenGet({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/identitiesTokenPut.ts b/src/client/service/identitiesTokenPut.ts index c06ad8106..261b88a12 100644 --- a/src/client/service/identitiesTokenPut.ts +++ b/src/client/service/identitiesTokenPut.ts @@ -67,7 +67,7 @@ function identitiesTokenPut({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysCertsChainGet.ts b/src/client/service/keysCertsChainGet.ts index 94418b7b6..fed99bf2a 100644 --- a/src/client/service/keysCertsChainGet.ts +++ b/src/client/service/keysCertsChainGet.ts @@ -34,7 +34,7 @@ function keysCertsChainGet({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysCertsGet.ts b/src/client/service/keysCertsGet.ts index da8792aa1..1b8222612 100644 --- a/src/client/service/keysCertsGet.ts +++ b/src/client/service/keysCertsGet.ts @@ -30,7 +30,7 @@ function keysCertsGet({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysDecrypt.ts b/src/client/service/keysDecrypt.ts index 092e7f67b..b1a0f6bad 100644 --- a/src/client/service/keysDecrypt.ts +++ b/src/client/service/keysDecrypt.ts @@ -31,7 +31,7 @@ function keysDecrypt({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysEncrypt.ts b/src/client/service/keysEncrypt.ts index df8f4ff62..b8c5c60bb 100644 --- a/src/client/service/keysEncrypt.ts +++ b/src/client/service/keysEncrypt.ts @@ -31,7 +31,7 @@ function keysEncrypt({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairRenew.ts b/src/client/service/keysKeyPairRenew.ts index 3660c9bc5..ada854cad 100644 --- a/src/client/service/keysKeyPairRenew.ts +++ b/src/client/service/keysKeyPairRenew.ts @@ -31,7 +31,7 @@ function keysKeyPairRenew({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairReset.ts b/src/client/service/keysKeyPairReset.ts index 3d04f12aa..af3b25426 100644 --- a/src/client/service/keysKeyPairReset.ts +++ b/src/client/service/keysKeyPairReset.ts @@ -31,7 +31,7 @@ function keysKeyPairReset({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysKeyPairRoot.ts b/src/client/service/keysKeyPairRoot.ts index ad1eb3e5a..14f543d9f 100644 --- a/src/client/service/keysKeyPairRoot.ts +++ b/src/client/service/keysKeyPairRoot.ts @@ -31,7 +31,7 @@ function keysKeyPairRoot({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysPasswordChange.ts b/src/client/service/keysPasswordChange.ts index b96a44ca1..b1d116db5 100644 --- a/src/client/service/keysPasswordChange.ts +++ b/src/client/service/keysPasswordChange.ts @@ -29,7 +29,7 @@ function keysPasswordChange({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysSign.ts b/src/client/service/keysSign.ts index bae99915f..9c3aa2ab3 100644 --- a/src/client/service/keysSign.ts +++ b/src/client/service/keysSign.ts @@ -32,7 +32,7 @@ function keysSign({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/keysVerify.ts b/src/client/service/keysVerify.ts index a7cfaae3a..1c53fff74 100644 --- a/src/client/service/keysVerify.ts +++ b/src/client/service/keysVerify.ts @@ -33,7 +33,7 @@ function keysVerify({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/nodesAdd.ts b/src/client/service/nodesAdd.ts index 8c089ff0b..079d2eee2 100644 --- a/src/client/service/nodesAdd.ts +++ b/src/client/service/nodesAdd.ts @@ -74,7 +74,7 @@ function nodesAdd({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/nodesClaim.ts b/src/client/service/nodesClaim.ts index 4022e10c7..c9e1d6db9 100644 --- a/src/client/service/nodesClaim.ts +++ b/src/client/service/nodesClaim.ts @@ -77,7 +77,7 @@ function nodesClaim({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ nodesErrors.ErrorNodeGraphNodeIdNotFound, ]) && logger.error(e); return; diff --git a/src/client/service/nodesFind.ts b/src/client/service/nodesFind.ts index 4826f9d96..6c2061719 100644 --- a/src/client/service/nodesFind.ts +++ b/src/client/service/nodesFind.ts @@ -59,7 +59,7 @@ function nodesFind({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ nodesErrors.ErrorNodeGraphNodeIdNotFound, ]) && logger.error(e); return; diff --git a/src/client/service/nodesPing.ts b/src/client/service/nodesPing.ts index f86c8c1fa..5adc83f54 100644 --- a/src/client/service/nodesPing.ts +++ b/src/client/service/nodesPing.ts @@ -53,7 +53,7 @@ function nodesPing({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ nodesErrors.ErrorNodeGraphNodeIdNotFound, ]) && logger.error(e); return; diff --git a/src/client/service/notificationsClear.ts b/src/client/service/notificationsClear.ts index 8d1d501c1..acc05724e 100644 --- a/src/client/service/notificationsClear.ts +++ b/src/client/service/notificationsClear.ts @@ -33,7 +33,7 @@ function notificationsClear({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/notificationsRead.ts b/src/client/service/notificationsRead.ts index 60d55b7c7..4e6cbb92d 100644 --- a/src/client/service/notificationsRead.ts +++ b/src/client/service/notificationsRead.ts @@ -75,7 +75,7 @@ function notificationsRead({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/notificationsSend.ts b/src/client/service/notificationsSend.ts index c592aa476..fcdb72606 100644 --- a/src/client/service/notificationsSend.ts +++ b/src/client/service/notificationsSend.ts @@ -56,7 +56,7 @@ function notificationsSend({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ nodesErrors.ErrorNodeGraphNodeIdNotFound, ]) && logger.error(e); return; diff --git a/src/client/service/vaultsClone.ts b/src/client/service/vaultsClone.ts index 86129010d..ec60df21a 100644 --- a/src/client/service/vaultsClone.ts +++ b/src/client/service/vaultsClone.ts @@ -6,6 +6,7 @@ import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; import type Logger from '@matrixai/logger'; import type * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '../../grpc/utils'; +import * as grpcErrors from '../../grpc/errors'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; import * as nodesErrors from '../../nodes/errors'; import { validateSync } from '../../validation'; @@ -63,9 +64,10 @@ function vaultsClone({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ nodesErrors.ErrorNodeGraphNodeIdNotFound, vaultsErrors.ErrorVaultsNameConflict, + [grpcErrors.ErrorPolykeyRemote, vaultsErrors.ErrorVaultsVaultUndefined], ]) && logger.error(e); return; } diff --git a/src/client/service/vaultsCreate.ts b/src/client/service/vaultsCreate.ts index 4175a7de0..c181b4b76 100644 --- a/src/client/service/vaultsCreate.ts +++ b/src/client/service/vaultsCreate.ts @@ -39,8 +39,9 @@ function vaultsCreate({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [vaultsErrors.ErrorVaultsVaultDefined]) && - logger.error(e); + !clientUtils.isClientClientError(e, [ + vaultsErrors.ErrorVaultsVaultDefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsDelete.ts b/src/client/service/vaultsDelete.ts index 6aea1c1c0..61fbfbc27 100644 --- a/src/client/service/vaultsDelete.ts +++ b/src/client/service/vaultsDelete.ts @@ -1,5 +1,5 @@ import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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'; @@ -7,10 +7,8 @@ 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 { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsDelete({ @@ -37,24 +35,12 @@ function vaultsDelete({ call.request.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } await vaultManager.destroyVault(vaultId, tran); }); response.setSuccess(true); @@ -62,8 +48,9 @@ function vaultsDelete({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [vaultsErrors.ErrorVaultsVaultUndefined]) && - logger.error(e); + !clientUtils.isClientClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsList.ts b/src/client/service/vaultsList.ts index 08646c59b..2e9f1a79a 100644 --- a/src/client/service/vaultsList.ts +++ b/src/client/service/vaultsList.ts @@ -40,7 +40,7 @@ function vaultsList({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsLog.ts b/src/client/service/vaultsLog.ts index 88873dca5..32d014b05 100644 --- a/src/client/service/vaultsLog.ts +++ b/src/client/service/vaultsLog.ts @@ -1,16 +1,14 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/types'; +import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type Logger from '@matrixai/logger'; import type * as grpc from '@grpc/grpc-js'; import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsLog({ @@ -36,24 +34,12 @@ function vaultsLog({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } // Getting the log const depth = call.request.getLogDepth(); let commitId: string | undefined = call.request.getCommitId(); @@ -80,7 +66,7 @@ function vaultsLog({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorVaultReferenceInvalid, ]) && logger.error(e); diff --git a/src/client/service/vaultsPermissionGet.ts b/src/client/service/vaultsPermissionGet.ts index d612f5b8c..86377f531 100644 --- a/src/client/service/vaultsPermissionGet.ts +++ b/src/client/service/vaultsPermissionGet.ts @@ -2,7 +2,7 @@ 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, VaultId, VaultActions } from '../../vaults/types'; +import type { VaultName, VaultActions } from '../../vaults/types'; import type ACL from '../../acl/ACL'; import type { NodeId, NodeIdEncoded } from 'nodes/types'; import type Logger from '@matrixai/logger'; @@ -10,10 +10,9 @@ import { IdInternal } from '@matrixai/id'; import * as grpcUtils from '../../grpc/utils'; import * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as nodesUtils from '../../nodes/utils'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsPermissionGet({ @@ -43,24 +42,12 @@ function vaultsPermissionGet({ call.request.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } // Getting permissions return [await acl.getVaultPerm(vaultId, tran), vaultId]; }, @@ -86,7 +73,9 @@ function vaultsPermissionGet({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e) && logger.error(e); + !clientUtils.isClientClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsPermissionSet.ts b/src/client/service/vaultsPermissionSet.ts index 335165ef7..9bc2a3b8d 100644 --- a/src/client/service/vaultsPermissionSet.ts +++ b/src/client/service/vaultsPermissionSet.ts @@ -1,12 +1,7 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { NodeId } from '../../nodes/types'; -import type { - VaultName, - VaultId, - VaultAction, - VaultActions, -} from '../../vaults/types'; +import type { VaultName, VaultAction, VaultActions } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type GestaltGraph from '../../gestalts/GestaltGraph'; import type ACL from '../../acl/ACL'; @@ -55,29 +50,28 @@ function vaultsPermissionSet({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const { nodeId, - vaultId, actions, }: { nodeId: NodeId; - vaultId: VaultId; actions: Array; } = validateSync( (keyPath, value) => { return matchSync(keyPath)( [['nodeId'], () => validationUtils.parseNodeId(value)], - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], [['actions'], () => value.map(validationUtils.parseVaultAction)], () => value, ); }, { nodeId: call.request.getNode()?.getNodeId(), - vaultId: call.request.getVault()?.getNameOrId(), actions: call.request.getVaultPermissionsList(), }, ); @@ -105,7 +99,7 @@ function vaultsPermissionSet({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, aclErrors.ErrorACLNodeIdMissing, nodesErrors.ErrorNodeGraphNodeIdNotFound, diff --git a/src/client/service/vaultsPermissionUnset.ts b/src/client/service/vaultsPermissionUnset.ts index 9b561b173..7906207a3 100644 --- a/src/client/service/vaultsPermissionUnset.ts +++ b/src/client/service/vaultsPermissionUnset.ts @@ -1,13 +1,14 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type { NodeId } from '../../nodes/types'; -import type { VaultName, VaultId, VaultAction } from '../../vaults/types'; +import type { VaultName, VaultAction } 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 type * as grpc from '@grpc/grpc-js'; +import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; @@ -45,29 +46,28 @@ function vaultsPermissionUnset({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const { nodeId, - vaultId, actions, }: { nodeId: NodeId; - vaultId: VaultId; actions: Array; } = validateSync( (keyPath, value) => { return matchSync(keyPath)( [['nodeId'], () => validationUtils.parseNodeId(value)], - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], [['actions'], () => value.map(validationUtils.parseVaultAction)], () => value, ); }, { nodeId: call.request.getNode()?.getNodeId(), - vaultId: call.request.getVault()?.getNameOrId(), actions: call.request.getVaultPermissionsList(), }, ); @@ -99,7 +99,7 @@ function vaultsPermissionUnset({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, gestaltsErrors.ErrorGestaltsGraphNodeIdMissing, ]) && logger.error(e); diff --git a/src/client/service/vaultsPull.ts b/src/client/service/vaultsPull.ts index 6f7d19106..00fa44880 100644 --- a/src/client/service/vaultsPull.ts +++ b/src/client/service/vaultsPull.ts @@ -1,16 +1,18 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; import type VaultManager from '../../vaults/VaultManager'; -import type { VaultName, VaultId } from '../../vaults/types'; +import type { VaultName } from '../../vaults/types'; import type { NodeId } from '../../nodes/types'; import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; import type Logger from '@matrixai/logger'; import type * as grpc from '@grpc/grpc-js'; import * as grpcUtils from '../../grpc/utils'; +import * as grpcErrors from '../../grpc/errors'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; import { validateSync } from '../../validation'; import * as validationUtils from '../../validation/utils'; import * as vaultsUtils from '../../vaults/utils'; +import * as vaultsErrors from '../../vaults/errors'; import * as nodesErrors from '../../nodes/errors'; import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; @@ -48,19 +50,19 @@ function vaultsPull({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const { - vaultId, nodeId, }: { - vaultId: VaultId; nodeId: NodeId | undefined; } = validateSync( (keyPath, value) => { return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], [ ['nodeId'], () => (value ? validationUtils.parseNodeId(value) : undefined), @@ -69,7 +71,6 @@ function vaultsPull({ ); }, { - vaultId: call.request.getVault()?.getNameOrId(), nodeId: call.request.getNode()?.getNodeId(), }, ); @@ -85,8 +86,10 @@ function vaultsPull({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, nodesErrors.ErrorNodeGraphNodeIdNotFound, + [grpcErrors.ErrorPolykeyRemote, vaultsErrors.ErrorVaultsVaultUndefined], ]) && logger.error(e); return; } diff --git a/src/client/service/vaultsRename.ts b/src/client/service/vaultsRename.ts index 9647d7ef1..29d2bb04b 100644 --- a/src/client/service/vaultsRename.ts +++ b/src/client/service/vaultsRename.ts @@ -1,16 +1,13 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/types'; +import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type Logger from '@matrixai/logger'; import type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsRename({ @@ -37,24 +34,12 @@ function vaultsRename({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const newName = call.request.getNewName() as VaultName; await vaultManager.renameVault(vaultId, newName, tran); response.setNameOrId(vaultsUtils.encodeVaultId(vaultId)); @@ -63,7 +48,7 @@ function vaultsRename({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorVaultsVaultDefined, ]) && logger.error(e); diff --git a/src/client/service/vaultsScan.ts b/src/client/service/vaultsScan.ts index 48556105e..c7a0def19 100644 --- a/src/client/service/vaultsScan.ts +++ b/src/client/service/vaultsScan.ts @@ -58,7 +58,7 @@ function vaultsScan({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ nodesErrors.ErrorNodeGraphNodeIdNotFound, ]) && logger.error(e); return; diff --git a/src/client/service/vaultsSecretsDelete.ts b/src/client/service/vaultsSecretsDelete.ts index 86a9a77b0..625c03cab 100644 --- a/src/client/service/vaultsSecretsDelete.ts +++ b/src/client/service/vaultsSecretsDelete.ts @@ -1,17 +1,15 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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 type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsDelete({ @@ -38,24 +36,12 @@ function vaultsSecretsDelete({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const secretName = call.request.getSecretName(); await vaultManager.withVaults( [vaultId], @@ -70,7 +56,7 @@ function vaultsSecretsDelete({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorSecretsSecretUndefined, ]) && logger.error(e); diff --git a/src/client/service/vaultsSecretsEdit.ts b/src/client/service/vaultsSecretsEdit.ts index 374b5d9dd..a40ea71e9 100644 --- a/src/client/service/vaultsSecretsEdit.ts +++ b/src/client/service/vaultsSecretsEdit.ts @@ -1,17 +1,15 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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 type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsEdit({ @@ -38,24 +36,12 @@ function vaultsSecretsEdit({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const secretName = call.request.getSecretName(); const secretContent = Buffer.from(call.request.getSecretContent()); await vaultManager.withVaults( @@ -71,7 +57,7 @@ function vaultsSecretsEdit({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorSecretsSecretUndefined, vaultsErrors.ErrorVaultRemoteDefined, diff --git a/src/client/service/vaultsSecretsGet.ts b/src/client/service/vaultsSecretsGet.ts index c5770db8e..4f826551f 100644 --- a/src/client/service/vaultsSecretsGet.ts +++ b/src/client/service/vaultsSecretsGet.ts @@ -1,17 +1,15 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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 type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsGet({ @@ -38,24 +36,12 @@ function vaultsSecretsGet({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const secretName = call.request.getSecretName(); const secretContent = await vaultManager.withVaults( [vaultId], @@ -70,7 +56,7 @@ function vaultsSecretsGet({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorSecretsSecretUndefined, ]) && logger.error(e); diff --git a/src/client/service/vaultsSecretsList.ts b/src/client/service/vaultsSecretsList.ts index b7c103cc7..a0774565f 100644 --- a/src/client/service/vaultsSecretsList.ts +++ b/src/client/service/vaultsSecretsList.ts @@ -1,17 +1,15 @@ import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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 { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsList({ @@ -37,24 +35,12 @@ function vaultsSecretsList({ call.request.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } return await vaultManager.withVaults( [vaultId], async (vault) => { @@ -73,8 +59,9 @@ function vaultsSecretsList({ return; } catch (e) { await genWritable.throw(e); - !clientUtils.isClientError(e, [vaultsErrors.ErrorVaultsVaultUndefined]) && - logger.error(e); + !clientUtils.isClientClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsMkdir.ts b/src/client/service/vaultsSecretsMkdir.ts index eaa4e8324..623a28ec9 100644 --- a/src/client/service/vaultsSecretsMkdir.ts +++ b/src/client/service/vaultsSecretsMkdir.ts @@ -1,17 +1,15 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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 type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsMkdir({ @@ -38,24 +36,12 @@ function vaultsSecretsMkdir({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } await vaultManager.withVaults( [vaultId], async (vault) => { @@ -71,7 +57,7 @@ function vaultsSecretsMkdir({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorVaultsRecursive, ]) && logger.error(e); diff --git a/src/client/service/vaultsSecretsNew.ts b/src/client/service/vaultsSecretsNew.ts index d89064985..c481a4cda 100644 --- a/src/client/service/vaultsSecretsNew.ts +++ b/src/client/service/vaultsSecretsNew.ts @@ -1,17 +1,15 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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 type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsNew({ @@ -38,24 +36,12 @@ function vaultsSecretsNew({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const secret = call.request.getSecretName(); const content = Buffer.from(call.request.getSecretContent()); await vaultManager.withVaults( @@ -71,7 +57,7 @@ function vaultsSecretsNew({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorSecretsSecretUndefined, ]) && logger.error(e); diff --git a/src/client/service/vaultsSecretsNewDir.ts b/src/client/service/vaultsSecretsNewDir.ts index 6cc7ad0f8..e9a0d0878 100644 --- a/src/client/service/vaultsSecretsNewDir.ts +++ b/src/client/service/vaultsSecretsNewDir.ts @@ -1,18 +1,16 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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 type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsNewDir({ @@ -41,24 +39,12 @@ function vaultsSecretsNewDir({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const secretsPath = call.request.getSecretDirectory(); await vaultManager.withVaults( [vaultId], @@ -73,8 +59,9 @@ function vaultsSecretsNewDir({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [vaultsErrors.ErrorVaultsVaultUndefined]) && - logger.error(e); + !clientUtils.isClientClientError(e, [ + vaultsErrors.ErrorVaultsVaultUndefined, + ]) && logger.error(e); return; } }; diff --git a/src/client/service/vaultsSecretsRename.ts b/src/client/service/vaultsSecretsRename.ts index 1b17420ff..9362c2b08 100644 --- a/src/client/service/vaultsSecretsRename.ts +++ b/src/client/service/vaultsSecretsRename.ts @@ -1,17 +1,15 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/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 type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; -import * as grpcUtils from '../../grpc/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; +import * as grpcUtils from '../../grpc/utils'; import * as vaultOps from '../../vaults/VaultOps'; import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsRename({ @@ -38,24 +36,14 @@ function vaultsSecretsRename({ call.request.getOldSecret()?.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getOldSecret()?.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId( + call.request.getOldSecret()?.getVault()?.getNameOrId(), + ); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const oldSecret = call.request.getOldSecret()?.getSecretName(); if (oldSecret == null) { throw new vaultsErrors.ErrorSecretsSecretUndefined(); @@ -74,7 +62,7 @@ function vaultsSecretsRename({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorSecretsSecretUndefined, ]) && logger.error(e); diff --git a/src/client/service/vaultsSecretsStat.ts b/src/client/service/vaultsSecretsStat.ts index fc173fe4b..78a7d2800 100644 --- a/src/client/service/vaultsSecretsStat.ts +++ b/src/client/service/vaultsSecretsStat.ts @@ -1,16 +1,14 @@ import type { DB } from '@matrixai/db'; import type VaultManager from '../../vaults/VaultManager'; -import type { VaultName, VaultId } from '../../vaults/types'; +import type { VaultName } from '../../vaults/types'; import type { Authenticate } from '../types'; import type Logger from '@matrixai/logger'; import type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; import * as grpcUtils from '../../grpc/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultOps from '../../vaults/VaultOps'; import * as secretsPB from '../../proto/js/polykey/v1/secrets/secrets_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsSecretsStat({ @@ -37,24 +35,12 @@ function vaultsSecretsStat({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } const secretName = call.request.getSecretName(); const stat = await vaultManager.withVaults( [vaultId], @@ -69,7 +55,7 @@ function vaultsSecretsStat({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorSecretsSecretUndefined, ]) && logger.error(e); diff --git a/src/client/service/vaultsVersion.ts b/src/client/service/vaultsVersion.ts index 7c755aa55..a3871b526 100644 --- a/src/client/service/vaultsVersion.ts +++ b/src/client/service/vaultsVersion.ts @@ -1,15 +1,13 @@ import type { DB } from '@matrixai/db'; import type { Authenticate } from '../types'; -import type { VaultName, VaultId } from '../../vaults/types'; +import type { VaultName } from '../../vaults/types'; import type VaultManager from '../../vaults/VaultManager'; import type Logger from '@matrixai/logger'; import type * as grpc from '@grpc/grpc-js'; -import { validateSync } from '../../validation'; -import * as validationUtils from '../../validation/utils'; +import * as vaultsUtils from '../../vaults/utils'; import * as grpcUtils from '../../grpc/utils'; import * as vaultsErrors from '../../vaults/errors'; import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb'; -import { matchSync } from '../../utils'; import * as clientUtils from '../utils'; function vaultsVersion({ @@ -37,24 +35,12 @@ function vaultsVersion({ call.request.getVault()?.getNameOrId() as VaultName, tran, ); - const { - vaultId, - }: { - vaultId: VaultId; - } = validateSync( - (keyPath, value) => { - return matchSync(keyPath)( - [ - ['vaultId'], - () => vaultIdFromName ?? validationUtils.parseVaultId(value), - ], - () => value, - ); - }, - { - vaultId: call.request.getVault()?.getNameOrId(), - }, - ); + const vaultId = + vaultIdFromName ?? + vaultsUtils.decodeVaultId(call.request.getVault()?.getNameOrId()); + if (vaultId == null) { + throw new vaultsErrors.ErrorVaultsVaultUndefined(); + } // Doing the deed const versionId = call.request.getVersionId(); const [latestOid, currentVersionId] = await vaultManager.withVaults( @@ -78,7 +64,7 @@ function vaultsVersion({ return; } catch (e) { callback(grpcUtils.fromError(e)); - !clientUtils.isClientError(e, [ + !clientUtils.isClientClientError(e, [ vaultsErrors.ErrorVaultsVaultUndefined, vaultsErrors.ErrorVaultReferenceInvalid, vaultsErrors.ErrorVaultReferenceMissing, diff --git a/src/client/types.ts b/src/client/types.ts index dc642800f..d06cdb11e 100644 --- a/src/client/types.ts +++ b/src/client/types.ts @@ -1,8 +1,14 @@ import type * as grpc from '@grpc/grpc-js'; +import type { Class } from '@matrixai/errors'; +import type ErrorPolykey from '../ErrorPolykey'; type Authenticate = ( metadataClient: grpc.Metadata, metadataServer?: grpc.Metadata, ) => Promise; -export type { Authenticate }; +type ClientClientErrors = Array< + Class> | Array>> +>; + +export type { Authenticate, ClientClientErrors }; diff --git a/src/client/utils/utils.ts b/src/client/utils/utils.ts index b77ac0e76..21bfaab20 100644 --- a/src/client/utils/utils.ts +++ b/src/client/utils/utils.ts @@ -3,12 +3,12 @@ import type { Interceptor, InterceptorOptions, } from '@grpc/grpc-js/build/src/client-interceptors'; -import type { Class } from '@matrixai/errors'; +import type ErrorPolykey from '../../ErrorPolykey'; 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 type { Authenticate, ClientClientErrors } from '../types'; import * as base64 from 'multiformats/bases/base64'; import * as grpc from '@grpc/grpc-js'; import * as validationErrors from '../../validation/errors'; @@ -18,7 +18,7 @@ import * as clientErrors from '../errors'; * Array of errors that are always considered to be "client errors" * (4xx errors in HTTP) in the context of the client service */ -const defaultClientErrors: Array> = [ +const defaultClientErrors: ClientClientErrors = [ validationErrors.ErrorValidation, clientErrors.ErrorClientAuthMissing, clientErrors.ErrorClientAuthFormat, @@ -154,16 +154,50 @@ function decodeAuthToSession( * context of a given handler can be supplied in the `extraClientErrors` * argument */ -function isClientError( - e: Error, - extraClientErrors?: Array>, +function isClientClientError( + thrownError: ErrorPolykey, + extraClientErrors?: ClientClientErrors, ): boolean { for (const error of defaultClientErrors) { - if (e instanceof error) return true; + if (Array.isArray(error)) { + let e = thrownError; + let matches = true; + for (const eType of error) { + if (e == null) { + matches = false; + break; + } + if (!(e instanceof eType)) { + matches = false; + break; + } + e = e.cause; + } + if (matches) return true; + } else if (thrownError instanceof error) { + return true; + } } if (extraClientErrors) { for (const error of extraClientErrors) { - if (e instanceof error) return true; + if (Array.isArray(error)) { + let e = thrownError; + let matches = true; + for (const eType of error) { + if (e == null) { + matches = false; + break; + } + if (!(e instanceof eType)) { + matches = false; + break; + } + e = e.cause; + } + if (matches) return true; + } else if (thrownError instanceof error) { + return true; + } } } return false; @@ -175,5 +209,5 @@ export { encodeAuthFromPassword, encodeAuthFromSession, decodeAuthToSession, - isClientError, + isClientClientError, }; diff --git a/tests/bin/vaults/vaults.test.ts b/tests/bin/vaults/vaults.test.ts index a8e6fa3df..52b5f4e4c 100644 --- a/tests/bin/vaults/vaults.test.ts +++ b/tests/bin/vaults/vaults.test.ts @@ -342,8 +342,8 @@ describe('CLI vaults', () => { targetNodeIdEncoded, ]; result = await testBinUtils.pkStdio([...command], {}, dataDir); - expect(result.exitCode).toBe(sysexits.DATAERR); - expect(result.stderr).toContain('ErrorValidation'); + expect(result.exitCode).toBe(sysexits.USAGE); + expect(result.stderr).toContain('ErrorVaultsVaultUndefined'); command = [ 'vaults', diff --git a/tests/vaults/VaultManager.test.ts b/tests/vaults/VaultManager.test.ts index c62824b1d..e4ed618aa 100644 --- a/tests/vaults/VaultManager.test.ts +++ b/tests/vaults/VaultManager.test.ts @@ -23,7 +23,6 @@ import KeyManager from '@/keys/KeyManager'; import PolykeyAgent from '@/PolykeyAgent'; import VaultManager from '@/vaults/VaultManager'; import * as vaultsErrors from '@/vaults/errors'; -import * as validationErrors from '@/validation/errors'; import NodeGraph from '@/nodes/NodeGraph'; import * as nodesUtils from '@/nodes/utils'; import Proxy from '@/network/Proxy'; @@ -744,7 +743,7 @@ describe('VaultManager', () => { remoteKeynode1Id, 'not-existing' as VaultName, ), - validationErrors.ErrorValidation, + vaultsErrors.ErrorVaultsVaultUndefined, ); } finally { await vaultManager?.stop(); From c37eddb10a5d6f73108c1fd54f40dce3c5d0fc22 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 6 Jun 2022 16:48:27 +1000 Subject: [PATCH 74/74] build: updated package.json --- package-lock.json | 78 +++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/package-lock.json b/package-lock.json index e90839fdd..04f328655 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "google-protobuf": "^3.14.0", "ip-num": "^1.3.3-0", "isomorphic-git": "^1.8.1", + "jest-junit": "^13.2.0", "jose": "^4.3.6", "lexicographic-integer": "^1.1.0", "multiformats": "^9.4.8", @@ -39,6 +40,7 @@ "prompts": "^2.4.1", "readable-stream": "^3.6.0", "resource-counter": "^1.2.4", + "rimraf": "^3.0.2", "threads": "^1.6.5", "utp-native": "^2.5.3", "uuid": "^8.3.0" @@ -3684,8 +3686,7 @@ "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 + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -3774,7 +3775,6 @@ "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" @@ -4128,8 +4128,7 @@ "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 + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "node_modules/console-control-strings": { "version": "1.1.0", @@ -5666,8 +5665,7 @@ "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 + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "node_modules/fsevents": { "version": "2.3.2", @@ -5832,7 +5830,6 @@ "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", @@ -6200,7 +6197,6 @@ "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" @@ -7347,6 +7343,20 @@ "node": ">=8" } }, + "node_modules/jest-junit": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.2.0.tgz", + "integrity": "sha512-B0XNlotl1rdsvFZkFfoa19mc634+rrd8E4Sskb92Bb8MmSXeWV9XJGUyctunZS1W410uAxcyYuPUGVnbcOH8cg==", + "dependencies": { + "mkdirp": "^1.0.4", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2", + "xml": "^1.0.1" + }, + "engines": { + "node": ">=10.12.0" + } + }, "node_modules/jest-leak-detector": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", @@ -8850,7 +8860,6 @@ "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" }, @@ -8871,6 +8880,17 @@ "minimist": "^1.2.5" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -9422,7 +9442,6 @@ "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" } @@ -10226,7 +10245,6 @@ "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" }, @@ -11662,6 +11680,11 @@ } } }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" + }, "node_modules/xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -18275,16 +18298,9 @@ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" }, "minimatch": { -<<<<<<< HEAD - "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, ->>>>>>> 55e00188 (build: updated dependencies and added incremental build) "requires": { "brace-expansion": "^1.1.7" } @@ -18302,35 +18318,11 @@ "minimist": "^1.2.5" } }, -<<<<<<< HEAD - "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==" }, -======= ->>>>>>> 55e00188 (build: updated dependencies and added incremental build) "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",