diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d2f420..8ca00fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,5 +11,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Updates for breaking `p2panda-js` API changes [#4](https://github.com/p2panda/shirokuma/pull/4) * Update dependencies [#5](https://github.com/p2panda/shirokuma/pull/5) +* Refactor code-base, remove caching layer, add "slim" and "inlined" builds [#12](https://github.com/p2panda/shirokuma/pull/12) [unreleased]: https://github.com/p2panda/shirokuma/compare/...HEAD diff --git a/README.md b/README.md index 7f3ba68..4989186 100644 --- a/README.md +++ b/README.md @@ -47,12 +47,9 @@ To install `shirokuma` run: npm i shirokuma ``` -## Usage - -`shirokuma` runs in web browsers and can be integrated in a bundle for example -via Webpack or Rollup. +## Example -```js +```typescript import { KeyPair, Session, initWebAssembly } from 'shirokuma'; // This method needs to be run once before to initialise the embedded @@ -75,40 +72,28 @@ const keyPair = new KeyPair(); const session = new Session('https://welle.liebechaos.org').setKeyPair(keyPair); // Compose your operation payload, according to chosen schema -const payload = { +const fields = { message: 'Hi there', }; -// Send new chat operation to the node -await session.create(payload, { schema: CHAT_SCHEMA }); - -// Query instances from the p2panda node -import { gql, useQuery } from '@apollo/client'; - -const GET_CHAT_MESSAGES = gql` - all_${CHAT_SCHEMA} { - fields { - message - } - } -`; - -const Chat = () => { - const { loading, error, data } = useQuery(GET_CHAT_MESSAGES); - - if (loading) return 'Loading...'; - if (error) return `Error! ${error.message}`; - - return ( - - ); -}; +// Send new chat message to the node +await session.create(fields, { schemaId: CHAT_SCHEMA }); ``` +## Usage + +`shirokuma` runs both in NodeJS and web browsers and comes as a ES, CommonJS +or UMD module. It can easily be integrated into Webpack, Rollup or other tools. + +Since `shirokuma` contains WebAssembly code, it is necessary to initialise it +before using the methods in the Browser. This initialisation step is not +required in NodeJS contexts. + +To make this step a little bit easier `shirokuma` inlines the WebAssembly code +as a base64 string which gets decoded automatically during initialisation. For +manual initialisation the package also comes with "slim" versions where you +need to provide a path to the ".wasm" file yourself. + ## Development ```bash @@ -125,20 +110,6 @@ npm test npm run build ``` -### Debug logging - -Enable debug logging for node environments by setting an environment variable: - -```bash -export DEBUG='shirokuma*' -``` - -Enable debug logging from a browser console by storing a key `debug` in local storage: - -```js -localStorage.debug = 'shirokuma*'; -``` - ### Documentation ```bash diff --git a/package-lock.json b/package-lock.json index 756d73d..a486dc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,6 @@ "version": "0.1.0", "license": "AGPL-3.0-or-later", "dependencies": { - "@types/debug": "^4.1.7", - "debug": "^4.3.4", "graphql": "^16.6.0", "graphql-request": "^5.1.0", "p2panda-js": "^0.6.0" @@ -20,15 +18,14 @@ "@babel/core": "^7.20.12", "@babel/preset-env": "^7.20.2", "@babel/register": "^7.18.9", - "@rollup/plugin-babel": "^6.0.3", + "@rollup/plugin-alias": "^4.0.3", "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-terser": "^0.4.0", "@rollup/plugin-typescript": "^11.0.0", "@tsconfig/node16": "^1.0.3", "@types/jest": "^29.4.0", - "@types/node": "^18.13.0", + "@types/node": "^18.14.0", "@typescript-eslint/eslint-plugin": "^5.52.0", "@typescript-eslint/parser": "^5.52.0", "cross-env": "^7.0.3", @@ -36,7 +33,7 @@ "eslint-config-prettier": "^8.6.0", "eslint-plugin-prettier": "^4.2.1", "fetch-mock-jest": "^1.5.1", - "jest": "^29.4.2", + "jest": "^29.4.3", "nodemon": "^2.0.20", "npm-run-all": "^4.1.5", "prettier": "^2.8.4", @@ -45,11 +42,12 @@ "rollup-plugin-dts": "^5.2.0", "ts-jest": "^29.0.5", "ts-node": "^10.9.1", + "tslib": "^2.5.0", "typedoc": "^0.23.25", "typescript": "^4.9.5" }, "engines": { - "node": ">= v16.0.0" + "node": ">= v17.5.0" } }, "node_modules/@ampproject/remapping": { @@ -2001,16 +1999,16 @@ } }, "node_modules/@jest/console": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.2.tgz", - "integrity": "sha512-0I/rEJwMpV9iwi9cDEnT71a5nNGK9lj8Z4+1pRAU2x/thVXCDnaTGrvxyK+cAqZTFVFCiR+hfVrP4l2m+dCmQg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.3.tgz", + "integrity": "sha512-W/o/34+wQuXlgqlPYTansOSiBnuxrTv61dEVkA6HNmpcgHLUjfaUbdqt6oVvOzaawwo9IdW9QOtMgQ1ScSZC4A==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", "slash": "^3.0.0" }, "engines": { @@ -2097,37 +2095,37 @@ } }, "node_modules/@jest/core": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.2.tgz", - "integrity": "sha512-KGuoQah0P3vGNlaS/l9/wQENZGNKGoWb+OPxh3gz+YzG7/XExvYu34MzikRndQCdM2S0tzExN4+FL37i6gZmCQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.3.tgz", + "integrity": "sha512-56QvBq60fS4SPZCuM7T+7scNrkGIe7Mr6PVIXUpu48ouvRaWOFqRPV91eifvFM0ay2HmfswXiGf97NGUN5KofQ==", "dev": true, "dependencies": { - "@jest/console": "^29.4.2", - "@jest/reporters": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.4.3", + "@jest/reporters": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.4.2", - "jest-config": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-resolve-dependencies": "^29.4.2", - "jest-runner": "^29.4.2", - "jest-runtime": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", - "jest-watcher": "^29.4.2", + "jest-changed-files": "^29.4.3", + "jest-config": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-resolve-dependencies": "^29.4.3", + "jest-runner": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", + "jest-watcher": "^29.4.3", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -2223,88 +2221,88 @@ } }, "node_modules/@jest/environment": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.2.tgz", - "integrity": "sha512-JKs3VUtse0vQfCaFGJRX1bir9yBdtasxziSyu+pIiEllAQOe4oQhdCYIf3+Lx+nGglFktSKToBnRJfD5QKp+NQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.3.tgz", + "integrity": "sha512-dq5S6408IxIa+lr54zeqce+QgI+CJT4nmmA+1yzFgtcsGK8c/EyiUb9XQOgz3BMKrRDfKseeOaxj2eO8LlD3lA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/fake-timers": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", - "jest-mock": "^29.4.2" + "jest-mock": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.2.tgz", - "integrity": "sha512-NUAeZVApzyaeLjfWIV/64zXjA2SS+NuUPHpAlO7IwVMGd5Vf9szTl9KEDlxY3B4liwLO31os88tYNHl6cpjtKQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.3.tgz", + "integrity": "sha512-iktRU/YsxEtumI9zsPctYUk7ptpC+AVLLk1Ax3AsA4g1C+8OOnKDkIQBDHtD5hA/+VtgMd5AWI5gNlcAlt2vxQ==", "dev": true, "dependencies": { - "expect": "^29.4.2", - "jest-snapshot": "^29.4.2" + "expect": "^29.4.3", + "jest-snapshot": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.2.tgz", - "integrity": "sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.3.tgz", + "integrity": "sha512-/6JWbkxHOP8EoS8jeeTd9dTfc9Uawi+43oLKHfp6zzux3U2hqOOVnV3ai4RpDYHOccL6g+5nrxpoc8DmJxtXVQ==", "dev": true, "dependencies": { - "jest-get-type": "^29.4.2" + "jest-get-type": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.2.tgz", - "integrity": "sha512-Ny1u0Wg6kCsHFWq7A/rW/tMhIedq2siiyHyLpHCmIhP7WmcAmd2cx95P+0xtTZlj5ZbJxIRQi4OPydZZUoiSQQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.3.tgz", + "integrity": "sha512-4Hote2MGcCTWSD2gwl0dwbCpBRHhE6olYEuTj8FMowdg3oQWNKr2YuxenPQYZ7+PfqPY1k98wKDU4Z+Hvd4Tiw==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.4.2", - "jest-mock": "^29.4.2", - "jest-util": "^29.4.2" + "jest-message-util": "^29.4.3", + "jest-mock": "^29.4.3", + "jest-util": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.2.tgz", - "integrity": "sha512-zCk70YGPzKnz/I9BNFDPlK+EuJLk21ur/NozVh6JVM86/YYZtZHqxFFQ62O9MWq7uf3vIZnvNA0BzzrtxD9iyg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.3.tgz", + "integrity": "sha512-8BQ/5EzfOLG7AaMcDh7yFCbfRLtsc+09E1RQmRBI4D6QQk4m6NSK/MXo+3bJrBN0yU8A2/VIcqhvsOLFmziioA==", "dev": true, "dependencies": { - "@jest/environment": "^29.4.2", - "@jest/expect": "^29.4.2", - "@jest/types": "^29.4.2", - "jest-mock": "^29.4.2" + "@jest/environment": "^29.4.3", + "@jest/expect": "^29.4.3", + "@jest/types": "^29.4.3", + "jest-mock": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.2.tgz", - "integrity": "sha512-10yw6YQe75zCgYcXgEND9kw3UZZH5tJeLzWv4vTk/2mrS1aY50A37F+XT2hPO5OqQFFnUWizXD8k1BMiATNfUw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.3.tgz", + "integrity": "sha512-sr2I7BmOjJhyqj9ANC6CTLsL4emMoka7HkQpcoMRlhCbQJjz2zsRzw0BDPiPyEFDXAbxKgGFYuQZiSJ1Y6YoTg==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -2317,9 +2315,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", + "jest-worker": "^29.4.3", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -2417,9 +2415,9 @@ } }, "node_modules/@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.25.16" @@ -2429,9 +2427,9 @@ } }, "node_modules/@jest/source-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.2.tgz", - "integrity": "sha512-tIoqV5ZNgYI9XCKXMqbYe5JbumcvyTgNN+V5QW4My033lanijvCD0D4PI9tBw4pRTqWOc00/7X3KVvUh+qnF4Q==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.15", @@ -2443,13 +2441,13 @@ } }, "node_modules/@jest/test-result": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.2.tgz", - "integrity": "sha512-HZsC3shhiHVvMtP+i55MGR5bPcc3obCFbA5bzIOb8pCjwBZf11cZliJncCgaVUbC5yoQNuGqCkC0Q3t6EItxZA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.3.tgz", + "integrity": "sha512-Oi4u9NfBolMq9MASPwuWTlC5WvmNRwI4S8YrQg5R5Gi47DYlBe3sh7ILTqi/LGrK1XUE4XY9KZcQJTH1WJCLLA==", "dev": true, "dependencies": { - "@jest/console": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.4.3", + "@jest/types": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -2458,14 +2456,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.2.tgz", - "integrity": "sha512-9Z2cVsD6CcObIVrWigHp2McRJhvCxL27xHtrZFgNC1RwnoSpDx6fZo8QYjJmziFlW9/hr78/3sxF54S8B6v8rg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.3.tgz", + "integrity": "sha512-yi/t2nES4GB4G0mjLc0RInCq/cNr9dNwJxcGg8sslajua5Kb4kmozAc+qPLzplhBgfw1vLItbjyHzUN92UXicw==", "dev": true, "dependencies": { - "@jest/test-result": "^29.4.2", + "@jest/test-result": "^29.4.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", + "jest-haste-map": "^29.4.3", "slash": "^3.0.0" }, "engines": { @@ -2482,22 +2480,22 @@ } }, "node_modules/@jest/transform": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", - "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.3.tgz", + "integrity": "sha512-8u0+fBGWolDshsFgPQJESkDa72da/EVwvL+II0trN2DR66wMwiQ9/CihaGfHdlLGFzbBZwMykFtxuwFdZqlKwg==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-haste-map": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.4.3", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -2593,12 +2591,12 @@ } }, "node_modules/@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.3.tgz", + "integrity": "sha512-bPYfw8V65v17m2Od1cv44FH+SiKW7w2Xu7trhcdTLUmSv85rfKsP+qXSjO4KGJr4dtPSzl/gvslZBXctf1qGEA==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -2792,32 +2790,38 @@ "node": ">= 8" } }, - "node_modules/@rollup/plugin-babel": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.3.tgz", - "integrity": "sha512-fKImZKppa1A/gX73eg4JGo+8kQr/q1HBQaCGKECZ0v4YBBv3lFqi14+7xyApECzvkLTHCifx+7ntcrvtBIRcpg==", + "node_modules/@rollup/plugin-alias": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-4.0.3.tgz", + "integrity": "sha512-ZuDWE1q4PQDhvm/zc5Prun8sBpLJy41DMptYrS6MhAy9s9kL/doN1613BWfEchGVfKxzliJ3BjbOPizXX38DbQ==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@rollup/pluginutils": "^5.0.1" + "slash": "^4.0.0" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", "rollup": "^1.20.0||^2.0.0||^3.0.0" }, "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - }, "rollup": { "optional": true } } }, + "node_modules/@rollup/plugin-alias/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@rollup/plugin-commonjs": { "version": "24.0.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz", @@ -2883,26 +2887,6 @@ "node": ">=10" } }, - "node_modules/@rollup/plugin-json": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", - "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.0.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz", @@ -3008,9 +2992,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.22", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.22.tgz", + "integrity": "sha512-6U6r2L7rnM7EG8G1tWzIjdB3QlsHF4slgcqXNN/SF0xJOAr0nDmT2GedlkyO3mrv8mDTJ24UuOMWR3diBrCvQQ==", "dev": true }, "node_modules/@sinonjs/commons": { @@ -3056,13 +3040,13 @@ "dev": true }, "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==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" @@ -3096,14 +3080,6 @@ "@babel/types": "^7.3.0" } }, - "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "dependencies": { - "@types/ms": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", @@ -3159,15 +3135,10 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "node_modules/@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" - }, "node_modules/@types/node": { - "version": "18.13.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", - "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==", + "version": "18.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz", + "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==", "dev": true }, "node_modules/@types/prettier": { @@ -3576,15 +3547,15 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/babel-jest": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.2.tgz", - "integrity": "sha512-vcghSqhtowXPG84posYkkkzcZsdayFkubUgbE3/1tuGbX7AQtwCkkNA/wIbB0BMjuCPoqTkiDyKN7Ty7d3uwNQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.3.tgz", + "integrity": "sha512-o45Wyn32svZE+LnMVWv/Z4x0SwtLbh4FyGcYtR20kIWd+rdrDZ9Fzq8Ml3MYLD+mZvEdzCjZsCnYZ2jpJyQ+Nw==", "dev": true, "dependencies": { - "@jest/transform": "^29.4.2", + "@jest/transform": "^29.4.3", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.4.2", + "babel-preset-jest": "^29.4.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -3692,9 +3663,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.2.tgz", - "integrity": "sha512-5HZRCfMeWypFEonRbEkwWXtNS1sQK159LhRVyRuLzyfVBxDy/34Tr/rg4YVi0SScSJ4fqeaR/OIeceJ/LaQ0pQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.3.tgz", + "integrity": "sha512-mB6q2q3oahKphy5V7CpnNqZOCkxxZ9aokf1eh82Dy3jQmg4xvM1tGrh5y6BQUJh4a3Pj9+eLfwvAZ7VNKg7H8Q==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -3769,12 +3740,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.2.tgz", - "integrity": "sha512-ecWdaLY/8JyfUDr0oELBMpj3R5I1L6ZqG+kRJmwqfHtLWuPrJStR0LUkvUhfykJWTsXXMnohsayN/twltBbDrQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.3.tgz", + "integrity": "sha512-gWx6COtSuma6n9bw+8/F+2PCXrIgxV/D1TJFnp6OyBK2cxPWg0K9p/sriNYeifKjpUkMViWQ09DSWtzJQRETsw==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^29.4.2", + "babel-plugin-jest-hoist": "^29.4.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -4180,6 +4151,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -4256,9 +4228,9 @@ } }, "node_modules/diff-sequences": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", - "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4803,16 +4775,16 @@ } }, "node_modules/expect": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.2.tgz", - "integrity": "sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.3.tgz", + "integrity": "sha512-uC05+Q7eXECFpgDrHdXA4k2rpMyStAYPItEDLyQDo5Ta7fVkJnNA/4zh/OIVkVVNZ1oOK1PipQoyNjuZ6sz6Dg==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2" + "@jest/expect-utils": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5943,15 +5915,15 @@ } }, "node_modules/jest": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.2.tgz", - "integrity": "sha512-+5hLd260vNIHu+7ZgMIooSpKl7Jp5pHKb51e73AJU3owd5dEo/RfVwHbA/na3C/eozrt3hJOLGf96c7EWwIAzg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.3.tgz", + "integrity": "sha512-XvK65feuEFGZT8OO0fB/QAQS+LGHvQpaadkH5p47/j3Ocqq3xf2pK9R+G0GzgfuhXVxEv76qCOOcMb5efLk6PA==", "dev": true, "dependencies": { - "@jest/core": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/core": "^29.4.3", + "@jest/types": "^29.4.3", "import-local": "^3.0.2", - "jest-cli": "^29.4.2" + "jest-cli": "^29.4.3" }, "bin": { "jest": "bin/jest.js" @@ -5969,9 +5941,9 @@ } }, "node_modules/jest-changed-files": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.2.tgz", - "integrity": "sha512-Qdd+AXdqD16PQa+VsWJpxR3kN0JyOCX1iugQfx5nUgAsI4gwsKviXkpclxOK9ZnwaY2IQVHz+771eAvqeOlfuw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.3.tgz", + "integrity": "sha512-Vn5cLuWuwmi2GNNbokPOEcvrXGSGrqVnPEZV7rC6P7ck07Dyw9RFnvWglnupSh+hGys0ajGtw/bc2ZgweljQoQ==", "dev": true, "dependencies": { "execa": "^5.0.0", @@ -5982,28 +5954,28 @@ } }, "node_modules/jest-circus": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.2.tgz", - "integrity": "sha512-wW3ztp6a2P5c1yOc1Cfrt5ozJ7neWmqeXm/4SYiqcSriyisgq63bwFj1NuRdSR5iqS0CMEYwSZd89ZA47W9zUg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.3.tgz", + "integrity": "sha512-Vw/bVvcexmdJ7MLmgdT3ZjkJ3LKu8IlpefYokxiqoZy6OCQ2VAm6Vk3t/qHiAGUXbdbJKJWnc8gH3ypTbB/OBw==", "dev": true, "dependencies": { - "@jest/environment": "^29.4.2", - "@jest/expect": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/environment": "^29.4.3", + "@jest/expect": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-runtime": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", + "jest-each": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", "p-limit": "^3.1.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -6091,21 +6063,21 @@ } }, "node_modules/jest-cli": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.2.tgz", - "integrity": "sha512-b+eGUtXq/K2v7SH3QcJvFvaUaCDS1/YAZBYz0m28Q/Ppyr+1qNaHmVYikOrbHVbZqYQs2IeI3p76uy6BWbXq8Q==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.3.tgz", + "integrity": "sha512-PiiAPuFNfWWolCE6t3ZrDXQc6OsAuM3/tVW0u27UWc1KE+n/HSn5dSE6B2juqN7WP+PP0jAcnKtGmI4u8GMYCg==", "dev": true, "dependencies": { - "@jest/core": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/core": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.4.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", + "jest-config": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -6195,31 +6167,31 @@ } }, "node_modules/jest-config": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.2.tgz", - "integrity": "sha512-919CtnXic52YM0zW4C1QxjG6aNueX1kBGthuMtvFtRTAxhKfJmiXC9qwHmi6o2josjbDz8QlWyY55F1SIVmCWA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.3.tgz", + "integrity": "sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.4.2", - "@jest/types": "^29.4.2", - "babel-jest": "^29.4.2", + "@jest/test-sequencer": "^29.4.3", + "@jest/types": "^29.4.3", + "babel-jest": "^29.4.3", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.4.2", - "jest-environment-node": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-runner": "^29.4.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", + "jest-circus": "^29.4.3", + "jest-environment-node": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-runner": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -6319,15 +6291,15 @@ } }, "node_modules/jest-diff": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", - "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.3.tgz", + "integrity": "sha512-YB+ocenx7FZ3T5O9lMVMeLYV4265socJKtkwgk/6YUz/VsEzYDkiMuMhWzZmxm3wDRQvayJu/PjkjjSkjoHsCA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6404,9 +6376,9 @@ } }, "node_modules/jest-docblock": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.2.tgz", - "integrity": "sha512-dV2JdahgClL34Y5vLrAHde3nF3yo2jKRH+GIYJuCpfqwEJZcikzeafVTGAjbOfKPG17ez9iWXwUYp7yefeCRag==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" @@ -6416,16 +6388,16 @@ } }, "node_modules/jest-each": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.2.tgz", - "integrity": "sha512-trvKZb0JYiCndc55V1Yh0Luqi7AsAdDWpV+mKT/5vkpnnFQfuQACV72IoRV161aAr6kAVIBpmYzwhBzm34vQkA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.3.tgz", + "integrity": "sha512-1ElHNAnKcbJb/b+L+7j0/w7bDvljw4gTv1wL9fYOczeJrbTbkMGQ5iQPFJ3eFQH19VPTx1IyfePdqSpePKss7Q==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "chalk": "^4.0.0", - "jest-get-type": "^29.4.2", - "jest-util": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-get-type": "^29.4.3", + "jest-util": "^29.4.3", + "pretty-format": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6502,46 +6474,46 @@ } }, "node_modules/jest-environment-node": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.2.tgz", - "integrity": "sha512-MLPrqUcOnNBc8zTOfqBbxtoa8/Ee8tZ7UFW7hRDQSUT+NGsvS96wlbHGTf+EFAT9KC3VNb7fWEM6oyvmxtE/9w==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.3.tgz", + "integrity": "sha512-gAiEnSKF104fsGDXNkwk49jD/0N0Bqu2K9+aMQXA6avzsA9H3Fiv1PW2D+gzbOSR705bWd2wJZRFEFpV0tXISg==", "dev": true, "dependencies": { - "@jest/environment": "^29.4.2", - "@jest/fake-timers": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/environment": "^29.4.3", + "@jest/fake-timers": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", - "jest-mock": "^29.4.2", - "jest-util": "^29.4.2" + "jest-mock": "^29.4.3", + "jest-util": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.2.tgz", - "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", - "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.3.tgz", + "integrity": "sha512-eZIgAS8tvm5IZMtKlR8Y+feEOMfo2pSQkmNbufdbMzMSn9nitgGxF1waM/+LbryO3OkMcKS98SUb+j/cQxp/vQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.4.3", + "jest-worker": "^29.4.3", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -6553,28 +6525,28 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.2.tgz", - "integrity": "sha512-Wa62HuRJmWXtX9F00nUpWlrbaH5axeYCdyRsOs/+Rb1Vb6+qWTlB5rKwCCRKtorM7owNwKsyJ8NRDUcZ8ghYUA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.3.tgz", + "integrity": "sha512-9yw4VC1v2NspMMeV3daQ1yXPNxMgCzwq9BocCwYrRgXe4uaEJPAN0ZK37nFBhcy3cUwEVstFecFLaTHpF7NiGA==", "dev": true, "dependencies": { - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", - "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.3.tgz", + "integrity": "sha512-TTciiXEONycZ03h6R6pYiZlSkvYgT0l8aa49z/DLSGYjex4orMUcafuLXYyyEDWB1RKglq00jzwY00Ei7yFNVg==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-diff": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6651,18 +6623,18 @@ } }, "node_modules/jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.3.tgz", + "integrity": "sha512-1Y8Zd4ZCN7o/QnWdMmT76If8LuDv23Z1DRovBj/vcSFNlGCJGoO8D1nJDw1AdyAGUk0myDLFGN5RbNeJyCRGCw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -6750,14 +6722,14 @@ } }, "node_modules/jest-mock": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.2.tgz", - "integrity": "sha512-x1FSd4Gvx2yIahdaIKoBjwji6XpboDunSJ95RpntGrYulI1ByuYQCKN/P7hvk09JB74IonU3IPLdkutEWYt++g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.3.tgz", + "integrity": "sha512-LjFgMg+xed9BdkPMyIJh+r3KeHt1klXPJYBULXVVAkbTaaKjPX1o1uVCAZADMEp/kOxGTwy/Ot8XbvgItOrHEg==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/node": "*", - "jest-util": "^29.4.2" + "jest-util": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6781,26 +6753,26 @@ } }, "node_modules/jest-regex-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", - "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.2.tgz", - "integrity": "sha512-RtKWW0mbR3I4UdkOrW7552IFGLYQ5AF9YrzD0FnIOkDu0rAMlA5/Y1+r7lhCAP4nXSBTaE7ueeqj6IOwZpgoqw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.3.tgz", + "integrity": "sha512-GPokE1tzguRyT7dkxBim4wSx6E45S3bOQ7ZdKEG+Qj0Oac9+6AwJPCk0TZh5Vu0xzeX4afpb+eDmgbmZFFwpOw==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", + "jest-haste-map": "^29.4.3", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -6810,13 +6782,13 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.2.tgz", - "integrity": "sha512-6pL4ptFw62rjdrPk7rRpzJYgcRqRZNsZTF1VxVTZMishbO6ObyWvX57yHOaNGgKoADtAHRFYdHQUEvYMJATbDg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.3.tgz", + "integrity": "sha512-uvKMZAQ3nmXLH7O8WAOhS5l0iWyT3WmnJBdmIHiV5tBbdaDZ1wqtNX04FONGoaFvSOSHBJxnwAVnSn1WHdGVaw==", "dev": true, "dependencies": { - "jest-regex-util": "^29.4.2", - "jest-snapshot": "^29.4.2" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6902,30 +6874,30 @@ } }, "node_modules/jest-runner": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.2.tgz", - "integrity": "sha512-wqwt0drm7JGjwdH+x1XgAl+TFPH7poowMguPQINYxaukCqlczAcNLJiK+OLxUxQAEWMdy+e6nHZlFHO5s7EuRg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.3.tgz", + "integrity": "sha512-GWPTEiGmtHZv1KKeWlTX9SIFuK19uLXlRQU43ceOQ2hIfA5yPEJC7AMkvFKpdCHx6pNEdOD+2+8zbniEi3v3gA==", "dev": true, "dependencies": { - "@jest/console": "^29.4.2", - "@jest/environment": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.4.3", + "@jest/environment": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.2", - "jest-environment-node": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-leak-detector": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-runtime": "^29.4.2", - "jest-util": "^29.4.2", - "jest-watcher": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-leak-detector": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-util": "^29.4.3", + "jest-watcher": "^29.4.3", + "jest-worker": "^29.4.3", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -7014,32 +6986,31 @@ } }, "node_modules/jest-runtime": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.2.tgz", - "integrity": "sha512-3fque9vtpLzGuxT9eZqhxi+9EylKK/ESfhClv4P7Y9sqJPs58LjVhTt8jaMp/pRO38agll1CkSu9z9ieTQeRrw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.4.2", - "@jest/fake-timers": "^29.4.2", - "@jest/globals": "^29.4.2", - "@jest/source-map": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.3.tgz", + "integrity": "sha512-F5bHvxSH+LvLV24vVB3L8K467dt3y3dio6V3W89dUz9nzvTpqd/HcT9zfYKL2aZPvD63vQFgLvaUX/UpUhrP6Q==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.3", + "@jest/fake-timers": "^29.4.3", + "@jest/globals": "^29.4.3", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-mock": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", - "semver": "^7.3.5", + "jest-haste-map": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-mock": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -7105,21 +7076,6 @@ "node": ">=8" } }, - "node_modules/jest-runtime/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-runtime/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -7142,9 +7098,9 @@ } }, "node_modules/jest-snapshot": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", - "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.3.tgz", + "integrity": "sha512-NGlsqL0jLPDW91dz304QTM/SNO99lpcSYYAjNiX0Ou+sSGgkanKBcSjCfp/pqmiiO1nQaOyLp6XQddAzRcx3Xw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -7153,23 +7109,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/expect-utils": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.4.2", + "expect": "^29.4.3", "graceful-fs": "^4.2.9", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-diff": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", "natural-compare": "^1.4.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "semver": "^7.3.5" }, "engines": { @@ -7262,12 +7218,12 @@ } }, "node_modules/jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.3.tgz", + "integrity": "sha512-ToSGORAz4SSSoqxDSylWX8JzkOQR7zoBtNRsA7e+1WUX5F8jrOwaNpuh1YfJHJKDHXLHmObv5eOjejUd+/Ws+Q==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7349,17 +7305,17 @@ } }, "node_modules/jest-validate": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.2.tgz", - "integrity": "sha512-tto7YKGPJyFbhcKhIDFq8B5od+eVWD/ySZ9Tvcp/NGCvYA4RQbuzhbwYWtIjMT5W5zA2W0eBJwu4HVw34d5G6Q==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.3.tgz", + "integrity": "sha512-J3u5v7aPQoXPzaar6GndAVhdQcZr/3osWSgTeKg5v574I9ybX/dTyH0AJFb5XgXIB7faVhf+rS7t4p3lL9qFaw==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.2", + "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^29.4.2" + "pretty-format": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7448,18 +7404,18 @@ } }, "node_modules/jest-watcher": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.2.tgz", - "integrity": "sha512-onddLujSoGiMJt+tKutehIidABa175i/Ays+QvKxCqBwp7fvxP3ZhKsrIdOodt71dKxqk4sc0LN41mWLGIK44w==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.3.tgz", + "integrity": "sha512-zwlXH3DN3iksoIZNk73etl1HzKyi5FuQdYLnkQKm5BW4n8HpoG59xSwpVdFrnh60iRRaRBGw0gcymIxjJENPcA==", "dev": true, "dependencies": { - "@jest/test-result": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.4.2", + "jest-util": "^29.4.3", "string-length": "^4.0.1" }, "engines": { @@ -7537,13 +7493,13 @@ } }, "node_modules/jest-worker": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", - "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.3.tgz", + "integrity": "sha512-GLHN/GTAAMEy5BFdvpUfzr9Dr80zQqBrh0fz1mtRMe05hqP45+HfQltu7oTBfduD0UeZs09d+maFtFYAXFWvAA==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.4.2", + "jest-util": "^29.4.3", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -7953,7 +7909,8 @@ "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==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/natural-compare": { "version": "1.4.0", @@ -8578,12 +8535,12 @@ } }, "node_modules/pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.3.tgz", + "integrity": "sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -9524,9 +9481,9 @@ } }, "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true }, "node_modules/tsutils": { @@ -9544,6 +9501,12 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9738,9 +9701,9 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -11346,16 +11309,16 @@ "dev": true }, "@jest/console": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.2.tgz", - "integrity": "sha512-0I/rEJwMpV9iwi9cDEnT71a5nNGK9lj8Z4+1pRAU2x/thVXCDnaTGrvxyK+cAqZTFVFCiR+hfVrP4l2m+dCmQg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.3.tgz", + "integrity": "sha512-W/o/34+wQuXlgqlPYTansOSiBnuxrTv61dEVkA6HNmpcgHLUjfaUbdqt6oVvOzaawwo9IdW9QOtMgQ1ScSZC4A==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", "slash": "^3.0.0" }, "dependencies": { @@ -11417,37 +11380,37 @@ } }, "@jest/core": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.2.tgz", - "integrity": "sha512-KGuoQah0P3vGNlaS/l9/wQENZGNKGoWb+OPxh3gz+YzG7/XExvYu34MzikRndQCdM2S0tzExN4+FL37i6gZmCQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.3.tgz", + "integrity": "sha512-56QvBq60fS4SPZCuM7T+7scNrkGIe7Mr6PVIXUpu48ouvRaWOFqRPV91eifvFM0ay2HmfswXiGf97NGUN5KofQ==", "dev": true, "requires": { - "@jest/console": "^29.4.2", - "@jest/reporters": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.4.3", + "@jest/reporters": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.4.2", - "jest-config": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-resolve-dependencies": "^29.4.2", - "jest-runner": "^29.4.2", - "jest-runtime": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", - "jest-watcher": "^29.4.2", + "jest-changed-files": "^29.4.3", + "jest-config": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-resolve-dependencies": "^29.4.3", + "jest-runner": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", + "jest-watcher": "^29.4.3", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -11510,73 +11473,73 @@ } }, "@jest/environment": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.2.tgz", - "integrity": "sha512-JKs3VUtse0vQfCaFGJRX1bir9yBdtasxziSyu+pIiEllAQOe4oQhdCYIf3+Lx+nGglFktSKToBnRJfD5QKp+NQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.3.tgz", + "integrity": "sha512-dq5S6408IxIa+lr54zeqce+QgI+CJT4nmmA+1yzFgtcsGK8c/EyiUb9XQOgz3BMKrRDfKseeOaxj2eO8LlD3lA==", "dev": true, "requires": { - "@jest/fake-timers": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/fake-timers": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", - "jest-mock": "^29.4.2" + "jest-mock": "^29.4.3" } }, "@jest/expect": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.2.tgz", - "integrity": "sha512-NUAeZVApzyaeLjfWIV/64zXjA2SS+NuUPHpAlO7IwVMGd5Vf9szTl9KEDlxY3B4liwLO31os88tYNHl6cpjtKQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.3.tgz", + "integrity": "sha512-iktRU/YsxEtumI9zsPctYUk7ptpC+AVLLk1Ax3AsA4g1C+8OOnKDkIQBDHtD5hA/+VtgMd5AWI5gNlcAlt2vxQ==", "dev": true, "requires": { - "expect": "^29.4.2", - "jest-snapshot": "^29.4.2" + "expect": "^29.4.3", + "jest-snapshot": "^29.4.3" } }, "@jest/expect-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.2.tgz", - "integrity": "sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.3.tgz", + "integrity": "sha512-/6JWbkxHOP8EoS8jeeTd9dTfc9Uawi+43oLKHfp6zzux3U2hqOOVnV3ai4RpDYHOccL6g+5nrxpoc8DmJxtXVQ==", "dev": true, "requires": { - "jest-get-type": "^29.4.2" + "jest-get-type": "^29.4.3" } }, "@jest/fake-timers": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.2.tgz", - "integrity": "sha512-Ny1u0Wg6kCsHFWq7A/rW/tMhIedq2siiyHyLpHCmIhP7WmcAmd2cx95P+0xtTZlj5ZbJxIRQi4OPydZZUoiSQQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.3.tgz", + "integrity": "sha512-4Hote2MGcCTWSD2gwl0dwbCpBRHhE6olYEuTj8FMowdg3oQWNKr2YuxenPQYZ7+PfqPY1k98wKDU4Z+Hvd4Tiw==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.4.2", - "jest-mock": "^29.4.2", - "jest-util": "^29.4.2" + "jest-message-util": "^29.4.3", + "jest-mock": "^29.4.3", + "jest-util": "^29.4.3" } }, "@jest/globals": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.2.tgz", - "integrity": "sha512-zCk70YGPzKnz/I9BNFDPlK+EuJLk21ur/NozVh6JVM86/YYZtZHqxFFQ62O9MWq7uf3vIZnvNA0BzzrtxD9iyg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.3.tgz", + "integrity": "sha512-8BQ/5EzfOLG7AaMcDh7yFCbfRLtsc+09E1RQmRBI4D6QQk4m6NSK/MXo+3bJrBN0yU8A2/VIcqhvsOLFmziioA==", "dev": true, "requires": { - "@jest/environment": "^29.4.2", - "@jest/expect": "^29.4.2", - "@jest/types": "^29.4.2", - "jest-mock": "^29.4.2" + "@jest/environment": "^29.4.3", + "@jest/expect": "^29.4.3", + "@jest/types": "^29.4.3", + "jest-mock": "^29.4.3" } }, "@jest/reporters": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.2.tgz", - "integrity": "sha512-10yw6YQe75zCgYcXgEND9kw3UZZH5tJeLzWv4vTk/2mrS1aY50A37F+XT2hPO5OqQFFnUWizXD8k1BMiATNfUw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.3.tgz", + "integrity": "sha512-sr2I7BmOjJhyqj9ANC6CTLsL4emMoka7HkQpcoMRlhCbQJjz2zsRzw0BDPiPyEFDXAbxKgGFYuQZiSJ1Y6YoTg==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -11589,9 +11552,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", + "jest-worker": "^29.4.3", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -11656,18 +11619,18 @@ } }, "@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { "@sinclair/typebox": "^0.25.16" } }, "@jest/source-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.2.tgz", - "integrity": "sha512-tIoqV5ZNgYI9XCKXMqbYe5JbumcvyTgNN+V5QW4My033lanijvCD0D4PI9tBw4pRTqWOc00/7X3KVvUh+qnF4Q==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.15", @@ -11676,26 +11639,26 @@ } }, "@jest/test-result": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.2.tgz", - "integrity": "sha512-HZsC3shhiHVvMtP+i55MGR5bPcc3obCFbA5bzIOb8pCjwBZf11cZliJncCgaVUbC5yoQNuGqCkC0Q3t6EItxZA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.3.tgz", + "integrity": "sha512-Oi4u9NfBolMq9MASPwuWTlC5WvmNRwI4S8YrQg5R5Gi47DYlBe3sh7ILTqi/LGrK1XUE4XY9KZcQJTH1WJCLLA==", "dev": true, "requires": { - "@jest/console": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.4.3", + "@jest/types": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.2.tgz", - "integrity": "sha512-9Z2cVsD6CcObIVrWigHp2McRJhvCxL27xHtrZFgNC1RwnoSpDx6fZo8QYjJmziFlW9/hr78/3sxF54S8B6v8rg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.3.tgz", + "integrity": "sha512-yi/t2nES4GB4G0mjLc0RInCq/cNr9dNwJxcGg8sslajua5Kb4kmozAc+qPLzplhBgfw1vLItbjyHzUN92UXicw==", "dev": true, "requires": { - "@jest/test-result": "^29.4.2", + "@jest/test-result": "^29.4.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", + "jest-haste-map": "^29.4.3", "slash": "^3.0.0" }, "dependencies": { @@ -11708,22 +11671,22 @@ } }, "@jest/transform": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", - "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.3.tgz", + "integrity": "sha512-8u0+fBGWolDshsFgPQJESkDa72da/EVwvL+II0trN2DR66wMwiQ9/CihaGfHdlLGFzbBZwMykFtxuwFdZqlKwg==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-haste-map": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.4.3", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -11794,12 +11757,12 @@ } }, "@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.3.tgz", + "integrity": "sha512-bPYfw8V65v17m2Od1cv44FH+SiKW7w2Xu7trhcdTLUmSv85rfKsP+qXSjO4KGJr4dtPSzl/gvslZBXctf1qGEA==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -11952,14 +11915,21 @@ "fastq": "^1.6.0" } }, - "@rollup/plugin-babel": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.3.tgz", - "integrity": "sha512-fKImZKppa1A/gX73eg4JGo+8kQr/q1HBQaCGKECZ0v4YBBv3lFqi14+7xyApECzvkLTHCifx+7ntcrvtBIRcpg==", + "@rollup/plugin-alias": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-4.0.3.tgz", + "integrity": "sha512-ZuDWE1q4PQDhvm/zc5Prun8sBpLJy41DMptYrS6MhAy9s9kL/doN1613BWfEchGVfKxzliJ3BjbOPizXX38DbQ==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@rollup/pluginutils": "^5.0.1" + "slash": "^4.0.0" + }, + "dependencies": { + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + } } }, "@rollup/plugin-commonjs": { @@ -12009,15 +11979,6 @@ } } }, - "@rollup/plugin-json": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz", - "integrity": "sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1" - } - }, "@rollup/plugin-node-resolve": { "version": "15.0.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz", @@ -12076,9 +12037,9 @@ } }, "@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.22", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.22.tgz", + "integrity": "sha512-6U6r2L7rnM7EG8G1tWzIjdB3QlsHF4slgcqXNN/SF0xJOAr0nDmT2GedlkyO3mrv8mDTJ24UuOMWR3diBrCvQQ==", "dev": true }, "@sinonjs/commons": { @@ -12124,13 +12085,13 @@ "dev": true }, "@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==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "dev": true, "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" @@ -12164,14 +12125,6 @@ "@babel/types": "^7.3.0" } }, - "@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "requires": { - "@types/ms": "*" - } - }, "@types/estree": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", @@ -12227,15 +12180,10 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" - }, "@types/node": { - "version": "18.13.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz", - "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==", + "version": "18.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz", + "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==", "dev": true }, "@types/prettier": { @@ -12510,15 +12458,15 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "babel-jest": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.2.tgz", - "integrity": "sha512-vcghSqhtowXPG84posYkkkzcZsdayFkubUgbE3/1tuGbX7AQtwCkkNA/wIbB0BMjuCPoqTkiDyKN7Ty7d3uwNQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.3.tgz", + "integrity": "sha512-o45Wyn32svZE+LnMVWv/Z4x0SwtLbh4FyGcYtR20kIWd+rdrDZ9Fzq8Ml3MYLD+mZvEdzCjZsCnYZ2jpJyQ+Nw==", "dev": true, "requires": { - "@jest/transform": "^29.4.2", + "@jest/transform": "^29.4.3", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.4.2", + "babel-preset-jest": "^29.4.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -12595,9 +12543,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.2.tgz", - "integrity": "sha512-5HZRCfMeWypFEonRbEkwWXtNS1sQK159LhRVyRuLzyfVBxDy/34Tr/rg4YVi0SScSJ4fqeaR/OIeceJ/LaQ0pQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.3.tgz", + "integrity": "sha512-mB6q2q3oahKphy5V7CpnNqZOCkxxZ9aokf1eh82Dy3jQmg4xvM1tGrh5y6BQUJh4a3Pj9+eLfwvAZ7VNKg7H8Q==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -12657,12 +12605,12 @@ } }, "babel-preset-jest": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.2.tgz", - "integrity": "sha512-ecWdaLY/8JyfUDr0oELBMpj3R5I1L6ZqG+kRJmwqfHtLWuPrJStR0LUkvUhfykJWTsXXMnohsayN/twltBbDrQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.3.tgz", + "integrity": "sha512-gWx6COtSuma6n9bw+8/F+2PCXrIgxV/D1TJFnp6OyBK2cxPWg0K9p/sriNYeifKjpUkMViWQ09DSWtzJQRETsw==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^29.4.2", + "babel-plugin-jest-hoist": "^29.4.3", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -12949,6 +12897,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -12999,9 +12948,9 @@ "dev": true }, "diff-sequences": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", - "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true }, "dir-glob": { @@ -13389,16 +13338,16 @@ "dev": true }, "expect": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.2.tgz", - "integrity": "sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.3.tgz", + "integrity": "sha512-uC05+Q7eXECFpgDrHdXA4k2rpMyStAYPItEDLyQDo5Ta7fVkJnNA/4zh/OIVkVVNZ1oOK1PipQoyNjuZ6sz6Dg==", "dev": true, "requires": { - "@jest/expect-utils": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2" + "@jest/expect-utils": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3" } }, "extract-files": { @@ -14206,21 +14155,21 @@ } }, "jest": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.2.tgz", - "integrity": "sha512-+5hLd260vNIHu+7ZgMIooSpKl7Jp5pHKb51e73AJU3owd5dEo/RfVwHbA/na3C/eozrt3hJOLGf96c7EWwIAzg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.3.tgz", + "integrity": "sha512-XvK65feuEFGZT8OO0fB/QAQS+LGHvQpaadkH5p47/j3Ocqq3xf2pK9R+G0GzgfuhXVxEv76qCOOcMb5efLk6PA==", "dev": true, "requires": { - "@jest/core": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/core": "^29.4.3", + "@jest/types": "^29.4.3", "import-local": "^3.0.2", - "jest-cli": "^29.4.2" + "jest-cli": "^29.4.3" } }, "jest-changed-files": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.2.tgz", - "integrity": "sha512-Qdd+AXdqD16PQa+VsWJpxR3kN0JyOCX1iugQfx5nUgAsI4gwsKviXkpclxOK9ZnwaY2IQVHz+771eAvqeOlfuw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.3.tgz", + "integrity": "sha512-Vn5cLuWuwmi2GNNbokPOEcvrXGSGrqVnPEZV7rC6P7ck07Dyw9RFnvWglnupSh+hGys0ajGtw/bc2ZgweljQoQ==", "dev": true, "requires": { "execa": "^5.0.0", @@ -14228,28 +14177,28 @@ } }, "jest-circus": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.2.tgz", - "integrity": "sha512-wW3ztp6a2P5c1yOc1Cfrt5ozJ7neWmqeXm/4SYiqcSriyisgq63bwFj1NuRdSR5iqS0CMEYwSZd89ZA47W9zUg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.3.tgz", + "integrity": "sha512-Vw/bVvcexmdJ7MLmgdT3ZjkJ3LKu8IlpefYokxiqoZy6OCQ2VAm6Vk3t/qHiAGUXbdbJKJWnc8gH3ypTbB/OBw==", "dev": true, "requires": { - "@jest/environment": "^29.4.2", - "@jest/expect": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/environment": "^29.4.3", + "@jest/expect": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-runtime": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", + "jest-each": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", "p-limit": "^3.1.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -14312,21 +14261,21 @@ } }, "jest-cli": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.2.tgz", - "integrity": "sha512-b+eGUtXq/K2v7SH3QcJvFvaUaCDS1/YAZBYz0m28Q/Ppyr+1qNaHmVYikOrbHVbZqYQs2IeI3p76uy6BWbXq8Q==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.3.tgz", + "integrity": "sha512-PiiAPuFNfWWolCE6t3ZrDXQc6OsAuM3/tVW0u27UWc1KE+n/HSn5dSE6B2juqN7WP+PP0jAcnKtGmI4u8GMYCg==", "dev": true, "requires": { - "@jest/core": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/core": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.4.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", + "jest-config": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -14383,31 +14332,31 @@ } }, "jest-config": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.2.tgz", - "integrity": "sha512-919CtnXic52YM0zW4C1QxjG6aNueX1kBGthuMtvFtRTAxhKfJmiXC9qwHmi6o2josjbDz8QlWyY55F1SIVmCWA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.3.tgz", + "integrity": "sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.4.2", - "@jest/types": "^29.4.2", - "babel-jest": "^29.4.2", + "@jest/test-sequencer": "^29.4.3", + "@jest/types": "^29.4.3", + "babel-jest": "^29.4.3", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.4.2", - "jest-environment-node": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-runner": "^29.4.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", + "jest-circus": "^29.4.3", + "jest-environment-node": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-runner": "^29.4.3", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -14470,15 +14419,15 @@ } }, "jest-diff": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", - "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.3.tgz", + "integrity": "sha512-YB+ocenx7FZ3T5O9lMVMeLYV4265socJKtkwgk/6YUz/VsEzYDkiMuMhWzZmxm3wDRQvayJu/PjkjjSkjoHsCA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" }, "dependencies": { "ansi-styles": { @@ -14533,25 +14482,25 @@ } }, "jest-docblock": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.2.tgz", - "integrity": "sha512-dV2JdahgClL34Y5vLrAHde3nF3yo2jKRH+GIYJuCpfqwEJZcikzeafVTGAjbOfKPG17ez9iWXwUYp7yefeCRag==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.2.tgz", - "integrity": "sha512-trvKZb0JYiCndc55V1Yh0Luqi7AsAdDWpV+mKT/5vkpnnFQfuQACV72IoRV161aAr6kAVIBpmYzwhBzm34vQkA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.3.tgz", + "integrity": "sha512-1ElHNAnKcbJb/b+L+7j0/w7bDvljw4gTv1wL9fYOczeJrbTbkMGQ5iQPFJ3eFQH19VPTx1IyfePdqSpePKss7Q==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "chalk": "^4.0.0", - "jest-get-type": "^29.4.2", - "jest-util": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-get-type": "^29.4.3", + "jest-util": "^29.4.3", + "pretty-format": "^29.4.3" }, "dependencies": { "ansi-styles": { @@ -14606,65 +14555,65 @@ } }, "jest-environment-node": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.2.tgz", - "integrity": "sha512-MLPrqUcOnNBc8zTOfqBbxtoa8/Ee8tZ7UFW7hRDQSUT+NGsvS96wlbHGTf+EFAT9KC3VNb7fWEM6oyvmxtE/9w==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.3.tgz", + "integrity": "sha512-gAiEnSKF104fsGDXNkwk49jD/0N0Bqu2K9+aMQXA6avzsA9H3Fiv1PW2D+gzbOSR705bWd2wJZRFEFpV0tXISg==", "dev": true, "requires": { - "@jest/environment": "^29.4.2", - "@jest/fake-timers": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/environment": "^29.4.3", + "@jest/fake-timers": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", - "jest-mock": "^29.4.2", - "jest-util": "^29.4.2" + "jest-mock": "^29.4.3", + "jest-util": "^29.4.3" } }, "jest-get-type": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.2.tgz", - "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true }, "jest-haste-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", - "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.3.tgz", + "integrity": "sha512-eZIgAS8tvm5IZMtKlR8Y+feEOMfo2pSQkmNbufdbMzMSn9nitgGxF1waM/+LbryO3OkMcKS98SUb+j/cQxp/vQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.4.3", + "jest-worker": "^29.4.3", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-leak-detector": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.2.tgz", - "integrity": "sha512-Wa62HuRJmWXtX9F00nUpWlrbaH5axeYCdyRsOs/+Rb1Vb6+qWTlB5rKwCCRKtorM7owNwKsyJ8NRDUcZ8ghYUA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.3.tgz", + "integrity": "sha512-9yw4VC1v2NspMMeV3daQ1yXPNxMgCzwq9BocCwYrRgXe4uaEJPAN0ZK37nFBhcy3cUwEVstFecFLaTHpF7NiGA==", "dev": true, "requires": { - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" } }, "jest-matcher-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", - "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.3.tgz", + "integrity": "sha512-TTciiXEONycZ03h6R6pYiZlSkvYgT0l8aa49z/DLSGYjex4orMUcafuLXYyyEDWB1RKglq00jzwY00Ei7yFNVg==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-diff": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.4.3" }, "dependencies": { "ansi-styles": { @@ -14719,18 +14668,18 @@ } }, "jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.3.tgz", + "integrity": "sha512-1Y8Zd4ZCN7o/QnWdMmT76If8LuDv23Z1DRovBj/vcSFNlGCJGoO8D1nJDw1AdyAGUk0myDLFGN5RbNeJyCRGCw==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -14793,14 +14742,14 @@ } }, "jest-mock": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.2.tgz", - "integrity": "sha512-x1FSd4Gvx2yIahdaIKoBjwji6XpboDunSJ95RpntGrYulI1ByuYQCKN/P7hvk09JB74IonU3IPLdkutEWYt++g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.3.tgz", + "integrity": "sha512-LjFgMg+xed9BdkPMyIJh+r3KeHt1klXPJYBULXVVAkbTaaKjPX1o1uVCAZADMEp/kOxGTwy/Ot8XbvgItOrHEg==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/node": "*", - "jest-util": "^29.4.2" + "jest-util": "^29.4.3" } }, "jest-pnp-resolver": { @@ -14811,23 +14760,23 @@ "requires": {} }, "jest-regex-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", - "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true }, "jest-resolve": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.2.tgz", - "integrity": "sha512-RtKWW0mbR3I4UdkOrW7552IFGLYQ5AF9YrzD0FnIOkDu0rAMlA5/Y1+r7lhCAP4nXSBTaE7ueeqj6IOwZpgoqw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.3.tgz", + "integrity": "sha512-GPokE1tzguRyT7dkxBim4wSx6E45S3bOQ7ZdKEG+Qj0Oac9+6AwJPCk0TZh5Vu0xzeX4afpb+eDmgbmZFFwpOw==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", + "jest-haste-map": "^29.4.3", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", + "jest-util": "^29.4.3", + "jest-validate": "^29.4.3", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -14891,40 +14840,40 @@ } }, "jest-resolve-dependencies": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.2.tgz", - "integrity": "sha512-6pL4ptFw62rjdrPk7rRpzJYgcRqRZNsZTF1VxVTZMishbO6ObyWvX57yHOaNGgKoADtAHRFYdHQUEvYMJATbDg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.3.tgz", + "integrity": "sha512-uvKMZAQ3nmXLH7O8WAOhS5l0iWyT3WmnJBdmIHiV5tBbdaDZ1wqtNX04FONGoaFvSOSHBJxnwAVnSn1WHdGVaw==", "dev": true, "requires": { - "jest-regex-util": "^29.4.2", - "jest-snapshot": "^29.4.2" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.4.3" } }, "jest-runner": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.2.tgz", - "integrity": "sha512-wqwt0drm7JGjwdH+x1XgAl+TFPH7poowMguPQINYxaukCqlczAcNLJiK+OLxUxQAEWMdy+e6nHZlFHO5s7EuRg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.3.tgz", + "integrity": "sha512-GWPTEiGmtHZv1KKeWlTX9SIFuK19uLXlRQU43ceOQ2hIfA5yPEJC7AMkvFKpdCHx6pNEdOD+2+8zbniEi3v3gA==", "dev": true, "requires": { - "@jest/console": "^29.4.2", - "@jest/environment": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.4.3", + "@jest/environment": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.2", - "jest-environment-node": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-leak-detector": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-runtime": "^29.4.2", - "jest-util": "^29.4.2", - "jest-watcher": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-leak-detector": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-runtime": "^29.4.3", + "jest-util": "^29.4.3", + "jest-watcher": "^29.4.3", + "jest-worker": "^29.4.3", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -14991,32 +14940,31 @@ } }, "jest-runtime": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.2.tgz", - "integrity": "sha512-3fque9vtpLzGuxT9eZqhxi+9EylKK/ESfhClv4P7Y9sqJPs58LjVhTt8jaMp/pRO38agll1CkSu9z9ieTQeRrw==", - "dev": true, - "requires": { - "@jest/environment": "^29.4.2", - "@jest/fake-timers": "^29.4.2", - "@jest/globals": "^29.4.2", - "@jest/source-map": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.3.tgz", + "integrity": "sha512-F5bHvxSH+LvLV24vVB3L8K467dt3y3dio6V3W89dUz9nzvTpqd/HcT9zfYKL2aZPvD63vQFgLvaUX/UpUhrP6Q==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.3", + "@jest/fake-timers": "^29.4.3", + "@jest/globals": "^29.4.3", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-mock": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", - "semver": "^7.3.5", + "jest-haste-map": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-mock": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.4.3", + "jest-snapshot": "^29.4.3", + "jest-util": "^29.4.3", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -15061,15 +15009,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -15088,9 +15027,9 @@ } }, "jest-snapshot": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", - "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.3.tgz", + "integrity": "sha512-NGlsqL0jLPDW91dz304QTM/SNO99lpcSYYAjNiX0Ou+sSGgkanKBcSjCfp/pqmiiO1nQaOyLp6XQddAzRcx3Xw==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -15099,23 +15038,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/expect-utils": "^29.4.3", + "@jest/transform": "^29.4.3", + "@jest/types": "^29.4.3", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.4.2", + "expect": "^29.4.3", "graceful-fs": "^4.2.9", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-diff": "^29.4.3", + "jest-get-type": "^29.4.3", + "jest-haste-map": "^29.4.3", + "jest-matcher-utils": "^29.4.3", + "jest-message-util": "^29.4.3", + "jest-util": "^29.4.3", "natural-compare": "^1.4.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.4.3", "semver": "^7.3.5" }, "dependencies": { @@ -15180,12 +15119,12 @@ } }, "jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.3.tgz", + "integrity": "sha512-ToSGORAz4SSSoqxDSylWX8JzkOQR7zoBtNRsA7e+1WUX5F8jrOwaNpuh1YfJHJKDHXLHmObv5eOjejUd+/Ws+Q==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -15245,17 +15184,17 @@ } }, "jest-validate": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.2.tgz", - "integrity": "sha512-tto7YKGPJyFbhcKhIDFq8B5od+eVWD/ySZ9Tvcp/NGCvYA4RQbuzhbwYWtIjMT5W5zA2W0eBJwu4HVw34d5G6Q==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.3.tgz", + "integrity": "sha512-J3u5v7aPQoXPzaar6GndAVhdQcZr/3osWSgTeKg5v574I9ybX/dTyH0AJFb5XgXIB7faVhf+rS7t4p3lL9qFaw==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.4.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.2", + "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^29.4.2" + "pretty-format": "^29.4.3" }, "dependencies": { "ansi-styles": { @@ -15316,18 +15255,18 @@ } }, "jest-watcher": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.2.tgz", - "integrity": "sha512-onddLujSoGiMJt+tKutehIidABa175i/Ays+QvKxCqBwp7fvxP3ZhKsrIdOodt71dKxqk4sc0LN41mWLGIK44w==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.3.tgz", + "integrity": "sha512-zwlXH3DN3iksoIZNk73etl1HzKyi5FuQdYLnkQKm5BW4n8HpoG59xSwpVdFrnh60iRRaRBGw0gcymIxjJENPcA==", "dev": true, "requires": { - "@jest/test-result": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/test-result": "^29.4.3", + "@jest/types": "^29.4.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.4.2", + "jest-util": "^29.4.3", "string-length": "^4.0.1" }, "dependencies": { @@ -15383,13 +15322,13 @@ } }, "jest-worker": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", - "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.3.tgz", + "integrity": "sha512-GLHN/GTAAMEy5BFdvpUfzr9Dr80zQqBrh0fz1mtRMe05hqP45+HfQltu7oTBfduD0UeZs09d+maFtFYAXFWvAA==", "dev": true, "requires": { "@types/node": "*", - "jest-util": "^29.4.2", + "jest-util": "^29.4.3", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -15705,7 +15644,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "natural-compare": { "version": "1.4.0", @@ -16161,12 +16101,12 @@ } }, "pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.3.tgz", + "integrity": "sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -16838,9 +16778,9 @@ } }, "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true }, "tsutils": { @@ -16850,6 +16790,14 @@ "dev": true, "requires": { "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "type-check": { @@ -16983,9 +16931,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.12", diff --git a/package.json b/package.json index 4275ed7..46f633b 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,16 @@ "exports": { ".": { "types": "./lib/cjs/index.d.ts", + "node": "./lib/node/index.cjs", "import": "./lib/esm/index.js", "default": "./lib/cjs/index.cjs" }, + "./slim": { + "types": "./lib/cjs-slim/index.d.ts", + "node": "./lib/node/index.cjs", + "import": "./lib/esm-slim/index.js", + "default": "./lib/cjs-slim/index.cjs" + }, "./package.json": "./package.json" }, "scripts": { @@ -19,13 +26,13 @@ "clear": "rimraf ./lib", "docs": "typedoc src/index.ts", "lint": "eslint --ext .ts .", - "rollup": "rollup -c", + "rollup": "rollup -c rollup.config.ts --configPlugin typescript", "test": "cross-env NODE_ENV=development jest --coverage=$npm_config_coverage", "test:watch": "nodemon --watch '../p2panda-rs/src/*' --watch './src/*' --exec 'npm test' --ext js,ts,json", "typecheck": "tsc --noEmit" }, "engines": { - "node": ">= v16.0.0" + "node": ">= v17.5.0" }, "files": [ "lib" @@ -49,15 +56,14 @@ "@babel/core": "^7.20.12", "@babel/preset-env": "^7.20.2", "@babel/register": "^7.18.9", - "@rollup/plugin-babel": "^6.0.3", + "@rollup/plugin-alias": "^4.0.3", "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-terser": "^0.4.0", "@rollup/plugin-typescript": "^11.0.0", "@tsconfig/node16": "^1.0.3", "@types/jest": "^29.4.0", - "@types/node": "^18.13.0", + "@types/node": "^18.14.0", "@typescript-eslint/eslint-plugin": "^5.52.0", "@typescript-eslint/parser": "^5.52.0", "cross-env": "^7.0.3", @@ -65,7 +71,7 @@ "eslint-config-prettier": "^8.6.0", "eslint-plugin-prettier": "^4.2.1", "fetch-mock-jest": "^1.5.1", - "jest": "^29.4.2", + "jest": "^29.4.3", "nodemon": "^2.0.20", "npm-run-all": "^4.1.5", "prettier": "^2.8.4", @@ -74,12 +80,11 @@ "rollup-plugin-dts": "^5.2.0", "ts-jest": "^29.0.5", "ts-node": "^10.9.1", + "tslib": "^2.5.0", "typedoc": "^0.23.25", "typescript": "^4.9.5" }, "dependencies": { - "@types/debug": "^4.1.7", - "debug": "^4.3.4", "graphql": "^16.6.0", "graphql-request": "^5.1.0", "p2panda-js": "^0.6.0" diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 11ac54a..0000000 --- a/rollup.config.js +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -import pluginCommonJS from '@rollup/plugin-commonjs'; -import pluginDts from 'rollup-plugin-dts'; -import pluginJSON from '@rollup/plugin-json'; -import pluginTerser from '@rollup/plugin-terser'; -import pluginTypeScript from '@rollup/plugin-typescript'; -import { babel as pluginBabel } from '@rollup/plugin-babel'; -import { nodeResolve as pluginNodeResolve } from '@rollup/plugin-node-resolve'; - -const SRC_DIR = 'src'; -const DIST_DIR = 'lib'; - -const name = 'shirokuma'; -const input = `./${SRC_DIR}/index.ts`; -const sourcemap = true; - -function config(format) { - // Determine suffix of output files. For CommonJS builds we choose `.cjs`. - const ext = format === 'cjs' ? 'cjs' : 'js'; - - return [ - { - input, - output: [ - { - name, - file: `${DIST_DIR}/${format}/index.${ext}`, - format, - sourcemap, - }, - { - name, - file: `${DIST_DIR}/${format}/index.min.js`, - format, - sourcemap, - plugins: [pluginTerser()], - }, - ], - plugins: [ - pluginTypeScript(), - pluginNodeResolve({ - browser: true, - }), - pluginCommonJS({ - extensions: ['.js', '.ts'], - }), - pluginJSON(), - pluginBabel({ - babelHelpers: 'bundled', - compact: false, - }), - ], - }, - { - input, - output: { - file: `${DIST_DIR}/${format}/index.d.ts`, - format, - }, - plugins: [pluginDts()], - }, - ]; -} - -export default [...config('esm'), ...config('cjs'), ...config('umd')]; diff --git a/rollup.config.ts b/rollup.config.ts new file mode 100644 index 0000000..bc21d69 --- /dev/null +++ b/rollup.config.ts @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import fs from 'fs'; + +import pluginAlias from '@rollup/plugin-alias'; +import pluginCommonJS from '@rollup/plugin-commonjs'; +import pluginDts from 'rollup-plugin-dts'; +import pluginTerser from '@rollup/plugin-terser'; +import pluginTypeScript from '@rollup/plugin-typescript'; +import { nodeResolve as pluginNodeResolve } from '@rollup/plugin-node-resolve'; + +import type { + RollupOptions, + Plugin, + ModuleFormat, + OutputOptions, +} from 'rollup'; + +type BuildMode = 'inline' | 'slim' | 'node'; + +type BuildName = string; + +type Config = { + format: ModuleFormat; + mode: BuildMode; +}; + +const SRC_DIR = 'src'; +const DIST_DIR = 'lib'; +const BUILD_FILE_NAME = 'index'; +const USE_SOURCEMAP = true; + +// Helper to load `package.json` file +const pkg = JSON.parse( + fs.readFileSync(new URL('./package.json', import.meta.url), { + encoding: 'utf8', + }), +); + +// Returns the name of the sub-directory which will be created in the target +// folder for each build. +function getBuildName({ format, mode }: Config): BuildName { + if (mode === 'node') { + return 'node'; + } else if (mode === 'inline') { + return format; + } else { + return `${format}-slim`; + } +} + +// Returns the output file options for each build. +function getOutputs({ format, mode }: Config): OutputOptions[] { + const result: OutputOptions[] = []; + + const dirName = getBuildName({ format, mode }); + const sourcemap = USE_SOURCEMAP; + + // Determine suffix of output files. For CommonJS builds we choose `.cjs`. + const ext = format === 'cjs' ? 'cjs' : 'js'; + + result.push({ + name: pkg.name, + file: `${DIST_DIR}/${dirName}/${BUILD_FILE_NAME}.${ext}`, + format, + sourcemap, + }); + + // Provide a minified version for non-NodeJS builds + if (mode !== 'node') { + result.push({ + name: pkg.name, + file: `${DIST_DIR}/${dirName}/${BUILD_FILE_NAME}.min.js`, + format, + sourcemap, + plugins: [pluginTerser()], + }); + } + + return result; +} + +function getPlugins({ format, mode }: Config): Plugin[] { + const result: Plugin[] = []; + + // Convert external CommonJS- to ES6 modules + result.push( + pluginCommonJS({ + extensions: ['.js', '.ts'], + }), + ); + + // In umd builds we're bundling the dependencies as well, we need this plugin + // here to help locating external dependencies + if (format === 'umd') { + result.push( + pluginNodeResolve({ + // Use the "browser" module resolutions in the dependencies' package.json + browser: true, + }), + ); + } + + // Whenever we want to build a "slim" version of shirokuma we have to import + // the "slim" version of p2panda-js. + // + // The "slim" version does not contain the WebAssembly inlined (as a base64 + // string) and is therefore smaller. + if (mode === 'slim') { + result.push( + pluginAlias({ + entries: [{ find: 'p2panda-js', replacement: 'p2panda-js/slim' }], + }), + ); + } + + // Compile TypeScript source code to JavaScript + result.push(pluginTypeScript()); + + return result; +} + +function config({ format, mode }: Config): RollupOptions[] { + const result: RollupOptions[] = []; + + // Determine entry point in `src` + const input = `./${SRC_DIR}/index.ts`; + + // Determine where files of this build get written to + const output = getOutputs({ format, mode }); + + // Determine plugins which will be used to process this build + const plugins = getPlugins({ format, mode }); + + // Treat all npm dependencies as external, we don't want to include them in + // our bundle. + // + // Only "umd" bundles contain all dependencies bundled as well. That's a + // shame, but we hope that this will account for the "quick" uses of + // shirokuma. + const external = format === 'umd' ? [] : Object.keys(pkg.dependencies); + + // Package build + result.push({ + input, + output, + plugins, + external, + }); + + // Generate TypeScript definition file for each build + const dirName = getBuildName({ format, mode }); + result.push({ + input, + output: { + file: `${DIST_DIR}/${dirName}/${BUILD_FILE_NAME}.d.ts`, + format, + }, + plugins: [pluginDts()], + }); + + return result; +} + +export default [ + ...config({ + format: 'umd', + mode: 'inline', + }), + ...config({ + format: 'cjs', + mode: 'inline', + }), + ...config({ + format: 'cjs', + mode: 'slim', + }), + ...config({ + format: 'esm', + mode: 'inline', + }), + ...config({ + format: 'esm', + mode: 'slim', + }), + ...config({ + format: 'cjs', + mode: 'node', + }), +]; diff --git a/src/document/document.test.ts b/src/document/document.test.ts deleted file mode 100644 index 8d09cfb..0000000 --- a/src/document/document.test.ts +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -import { KeyPair } from '../identity'; -import { Session } from '../session'; -import { createDocument, deleteDocument, updateDocument } from '.'; - -import type { Fields } from '../types'; - -import { - authorFixture, - entryFixture, - encodedEntryFixture, - entryArgsFixture, - schemaFixture, -} from '../../test/fixtures'; - -jest.mock('../session'); - -const MOCK_SERVER_URL = 'http://localhost:2020'; - -describe('document', () => { - describe('createDocument', () => { - it('creates a document', async () => { - const keyPair = new KeyPair(authorFixture().privateKey); - const session: Session = new Session(MOCK_SERVER_URL); - session.setKeyPair(keyPair); - - const asyncFunctionMock = jest - .fn() - .mockResolvedValue(entryArgsFixture(1)); - jest.spyOn(session, 'getNextArgs').mockImplementation(asyncFunctionMock); - - const fields = entryFixture(1).operation?.fields as Fields; - - const entryEncoded = await createDocument(fields, { - keyPair, - schema: schemaFixture(), - session, - }); - - expect(entryEncoded).toEqual(encodedEntryFixture(1).entryBytes); - }); - }); - - describe('updateDocument', () => { - it('updates a document', async () => { - const keyPair = new KeyPair(authorFixture().privateKey); - const session = new Session(MOCK_SERVER_URL); - session.setKeyPair(keyPair); - - const asyncFunctionMock = jest - .fn() - .mockResolvedValue(entryArgsFixture(2)); - jest.spyOn(session, 'getNextArgs').mockImplementation(asyncFunctionMock); - - // These are the fields for an update operation - const fields = entryFixture(2).operation?.fields as Fields; - - const previous = entryFixture(2).operation?.previous as string[]; - - const entryEncoded = await updateDocument(previous, fields, { - keyPair, - schema: schemaFixture(), - session, - }); - - expect(entryEncoded).toEqual(encodedEntryFixture(2).entryBytes); - }); - }); - - describe('deleteDocument', () => { - it('deletes a document', async () => { - const keyPair = new KeyPair(authorFixture().privateKey); - const session = new Session(MOCK_SERVER_URL); - session.setKeyPair(keyPair); - - const asyncFunctionMock = jest - .fn() - .mockResolvedValue(entryArgsFixture(4)); - jest.spyOn(session, 'getNextArgs').mockImplementation(asyncFunctionMock); - - const previous = entryFixture(4).operation?.previous as string[]; - - const entryEncoded = await deleteDocument(previous, { - keyPair, - schema: schemaFixture(), - session, - }); - - expect(entryEncoded).toEqual(encodedEntryFixture(4).entryBytes); - }); - }); -}); diff --git a/src/document/document.ts b/src/document/document.ts deleted file mode 100644 index e5eab32..0000000 --- a/src/document/document.ts +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -import debug from 'debug'; -import { encodeOperation } from 'p2panda-js'; - -import { getOperationFields } from '../operation'; -import { marshallRequestFields } from '../utils'; -import { signPublishEntry } from '../entry'; - -import type { Context } from '../session'; -import type { Fields } from '../types'; - -const log = debug('shirokuma:document'); - -/** - * Signs and publishes a CREATE operation for the given application data and - * matching document id. - * - * Returns the encoded entry that was created. - */ -export const createDocument = async ( - fields: Fields, - { keyPair, schema, session }: Context, -): Promise => { - log(`Creating document`, fields); - - const fieldsTagged = marshallRequestFields(fields); - const operationFields = getOperationFields(fieldsTagged); - const encodedOperation = encodeOperation({ - action: 'create', - schemaId: schema, - fields: operationFields, - }); - - const entryEncoded = signPublishEntry(encodedOperation, { - keyPair, - schema, - session, - }); - - return entryEncoded; -}; - -/** - * Signs and publishes an UPDATE operation for the given document id and - * fields. - * - * Returns the encoded entry that was created. - */ -export const updateDocument = async ( - previous: string[], - fields: Fields, - { keyPair, schema, session }: Context, -): Promise => { - log(`Updating document view`, { - previous, - fields, - }); - - const fieldsTagged = marshallRequestFields(fields); - const operationFields = getOperationFields(fieldsTagged); - - const encodedOperation = encodeOperation({ - action: 'update', - schemaId: schema, - previous, - fields: operationFields, - }); - - const entryEncoded = await signPublishEntry( - encodedOperation, - { - keyPair, - schema, - session, - }, - previous, - ); - - return entryEncoded; -}; - -/** - * Signs and publishes a DELETE operation for the given document id. - * - * Returns the encoded entry that was created. - */ -export const deleteDocument = async ( - previous: string[], - { keyPair, schema, session }: Context, -): Promise => { - log('Deleting document with view ', { previous }); - - const encodedOperation = encodeOperation({ - action: 'delete', - schemaId: schema, - previous, - }); - - const encodedEntry = await signPublishEntry( - encodedOperation, - { - keyPair, - schema, - session, - }, - previous, - ); - - return encodedEntry; -}; diff --git a/src/document/index.ts b/src/document/index.ts deleted file mode 100644 index 9c988e8..0000000 --- a/src/document/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -export { createDocument, updateDocument, deleteDocument } from './document'; diff --git a/src/entry.ts b/src/entry.ts new file mode 100644 index 0000000..dac466c --- /dev/null +++ b/src/entry.ts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { signAndEncodeEntry } from 'p2panda-js'; + +import type { EncodedOperation, EntryArgs, PublishVariables } from './types'; + +/** + * Sign and publish an entry given an encoded operation, key pair and entry + * arguments (log id, sequence number, backlink and skiplink). + * + * Returns the encoded entry, encoded operation and entry hash. + */ +export function signAndHashEntry( + operation: EncodedOperation, + entryArgs: EntryArgs, +): PublishVariables { + const { nextArgs, keyPair } = entryArgs; + + const entry = signAndEncodeEntry( + { + ...nextArgs, + operation, + }, + keyPair, + ); + + return { + entry, + operation, + }; +} diff --git a/src/entry/entry.ts b/src/entry/entry.ts deleted file mode 100644 index d3c4b83..0000000 --- a/src/entry/entry.ts +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -import debug from 'debug'; -import { signAndEncodeEntry, generateHash } from 'p2panda-js'; - -import { Context } from '../session'; - -const log = debug('shirokuma:entry'); - -/** - * Sign and publish an entry given a prepared `Operation`, `KeyPair` and - * `Session`. - * - * Sets next entry args on the supplied session's entry args cache. - * - * Returns the encoded entry. - */ -export const signPublishEntry = async ( - operation: string, - { keyPair, session }: Context, - viewId?: string[], -): Promise => { - const publicKey = keyPair.publicKey(); - const viewIdStr = viewId ? viewId.join('_') : undefined; - - log('Signing and publishing entry'); - const nextArgs = await session.getNextArgs(publicKey, viewIdStr); - - log('Retrieved next args for', { - publicKey, - viewId, - nextArgs, - }); - - const entry = signAndEncodeEntry( - { - ...nextArgs, - operation, - }, - keyPair, - ); - const entryHash = generateHash(entry); - log('Signed and encoded entry'); - - const publishNextArgs = await session.publish(entry, operation); - log('Published entry'); - - // Cache next entry args for next publish. - session.setNextArgs(publicKey, entryHash, publishNextArgs); - log('Cached next arguments'); - - return entry; -}; diff --git a/src/entry/index.ts b/src/entry/index.ts deleted file mode 100644 index 7cf9680..0000000 --- a/src/entry/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -export { signPublishEntry } from './entry'; diff --git a/src/graphql.ts b/src/graphql.ts new file mode 100644 index 0000000..e1d11ab --- /dev/null +++ b/src/graphql.ts @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { GraphQLClient, gql } from 'graphql-request'; + +import type { NextArgs, NextArgsVariables, PublishVariables } from './types'; + +/** + * GraphQL query to retrieve arguments to create a new entry from node. + */ +export const GQL_NEXT_ARGS = gql` + query NextArgs($publicKey: String!, $viewId: String) { + nextArgs(publicKey: $publicKey, viewId: $viewId) { + logId + seqNum + backlink + skiplink + } + } +`; + +/** + * GraphQL mutation to publish an entry and operation and retrieve arguments + * for encoding the next one. + */ +export const GQL_PUBLISH = gql` + mutation Publish($entry: String!, $operation: String!) { + publish(entry: $entry, operation: $operation) { + logId + seqNum + backlink + skiplink + } + } +`; + +/** + * Return arguments for constructing the next entry given author and document + * view id. + */ +export async function nextArgs( + client: GraphQLClient, + variables: NextArgsVariables, +): Promise { + if (!variables) { + throw new Error('Query variables must be provided'); + } + + if (!variables.publicKey) { + throw new Error("Author's public key must be provided"); + } + + const response = await client.request(GQL_NEXT_ARGS, variables); + return response.nextArgs; +} + +/** + * Publish an encoded entry and operation. + */ +export async function publish( + client: GraphQLClient, + variables: PublishVariables, +): Promise { + if (!variables) { + throw new Error('Query variables must be provided'); + } + + if (!variables.entry || !variables.operation) { + throw new Error('Encoded entry and operation must be provided'); + } + + const response = await client.request(GQL_PUBLISH, variables); + return response.publish; +} diff --git a/src/identity/index.ts b/src/identity/index.ts deleted file mode 100644 index 0244d58..0000000 --- a/src/identity/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -export { KeyPair } from 'p2panda-js'; diff --git a/src/index.ts b/src/index.ts index ad7eaa5..58099bd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,16 +1,8 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -import { initWebAssembly as init } from 'p2panda-js'; +export { initWebAssembly, KeyPair } from 'p2panda-js'; export { Session } from './session'; -export { KeyPair } from './identity'; -/** - * Initialise WebAssembly code. - * - * Run this method once in the beginning of your application before you access - * any method of `shirokuma`. - */ -export async function initWebAssembly() { - await init(); -} +export type { Options } from './session'; +export type { SchemaId, NextArgs, DocumentViewId, Fields } from './types'; diff --git a/src/operation.ts b/src/operation.ts new file mode 100644 index 0000000..acc096d --- /dev/null +++ b/src/operation.ts @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { encodeOperation } from 'p2panda-js'; + +import { signAndHashEntry } from './entry'; + +import type { + CreateArgs, + DeleteArgs, + EntryArgs, + PublishVariables, + UpdateArgs, +} from './types'; + +/** + * Encodes and signs a CREATE operation with the given data fields. + * + * Returns the encoded entry and encoded operation. + */ +export function createOperation( + args: CreateArgs, + entryArgs: EntryArgs, +): PublishVariables { + const operation = encodeOperation({ + action: 'create', + ...args, + }); + + return signAndHashEntry(operation, entryArgs); +} + +/** + * Encodes and signs an UPDATE operation for the given document view id and + * fields. + * + * Returns the encoded entry and encoded operation. + */ +export function updateOperation( + args: UpdateArgs, + entryArgs: EntryArgs, +): PublishVariables { + const operation = encodeOperation({ + action: 'update', + ...args, + }); + + return signAndHashEntry(operation, entryArgs); +} + +/** + * Encodes and signs a DELETE operation for the given document view id. + * + * Returns the encoded entry and encoded operation. + */ +export function deleteOperation( + args: DeleteArgs, + entryArgs: EntryArgs, +): PublishVariables { + const operation = encodeOperation({ + action: 'delete', + ...args, + }); + + return signAndHashEntry(operation, entryArgs); +} diff --git a/src/operation/index.ts b/src/operation/index.ts deleted file mode 100644 index 6bca145..0000000 --- a/src/operation/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -export { getOperationFields } from './operation'; diff --git a/src/operation/operation.test.ts b/src/operation/operation.test.ts deleted file mode 100644 index b5724b7..0000000 --- a/src/operation/operation.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -import { getOperationFields } from './'; -import { marshallRequestFields } from '../utils'; - -describe('operation', () => { - describe('getOperationFields', () => { - it('creates a WebAssembly OperationField', async () => { - const fields = marshallRequestFields({ - channel: 5, - temperature: 12.921, - message: 'chin chin', - serious: false, - }); - - const operationFields = getOperationFields(fields); - - const outputRepresentation = - 'OperationFields(OperationFields({"channel": Integer(5), "message": ' + - 'String("chin chin"), "serious": Boolean(false), "temperature": Float(12.921)}))'; - // @TODO: This does not exist anymore - // expect(operationFields.toString()).toEqual(outputRepresentation); - }); - }); -}); diff --git a/src/operation/operation.ts b/src/operation/operation.ts deleted file mode 100644 index ed6009e..0000000 --- a/src/operation/operation.ts +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -import debug from 'debug'; -import { OperationFields } from 'p2panda-js'; - -import type { FieldsTagged } from '../types'; - -const log = debug('shirokuma:operation'); - -/** - * Returns an operation fields instance for the given field contents and schema. - */ -export const getOperationFields = (fields: FieldsTagged): OperationFields => { - const operationFields = new OperationFields(); - - for (const [key, fieldValue] of fields.entries()) { - const { type, value } = fieldValue; - operationFields.insert(key, type, value); - } - - log('getOperationFields', operationFields.toString()); - return operationFields; -}; diff --git a/src/session.ts b/src/session.ts new file mode 100644 index 0000000..08c95cf --- /dev/null +++ b/src/session.ts @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { GraphQLClient } from 'graphql-request'; +import { generateHash, KeyPair } from 'p2panda-js'; + +import { createOperation, deleteOperation, updateOperation } from './operation'; +import { nextArgs, publish } from './graphql'; + +import type { + DocumentViewId, + EncodedEntry, + EncodedOperation, + Fields, + NextArgs, + PublicKey, + SchemaId, +} from './types'; + +/** + * Options we can pass in into methods which will override the globally set + * options for that session for that method call. + */ +export type Options = { + /** + * Key pair which is used for that method call to sign the entry. + */ + keyPair: KeyPair; + + /** + * Schema Id which is used for that method call to identify the schema of the + * document. + */ + schemaId: SchemaId; +}; + +/** + * Communicate with the p2panda network through a `Session` instance. + * + * `Session` provides a high-level interface to create data in the p2panda + * network by creating, updating and deleting documents following data schemas. + * It also provides a low-level API for creating entries on the Bamboo + * append-only log structure. + * + * A session is configured with the URL of a p2panda node, which may be running + * locally or on a remote machine. It is possible to set a fixed key pair + * and/or data schema for a session by calling `setKeyPair()` and `setSchemaId()` + * or you can also configure these through the `options` parameter of + * methods. + */ +export class Session { + /** + * Address of a p2panda node that we can connect to. + */ + readonly endpoint: string; + + /** + * A GraphQL client connected to the configured endpoint. + */ + readonly client: GraphQLClient; + + /** + * Initiates a new session. + * + * @param endpoint - URL of p2panda node + * @returns Session instance + */ + constructor(endpoint: Session['endpoint']) { + if (!endpoint) { + throw new Error('Missing `endpoint` parameter for creating a session'); + } + + this.endpoint = endpoint; + this.client = new GraphQLClient(endpoint); + } + + /** + * Globally configured schema id which is used as a default for all requests. + */ + #schemaId: SchemaId | null = null; + + /** + * Returns currently configured schema id. + * + * Throws if no schema id is configured. + * + * @returns SchemaId instance + */ + get schemaId(): SchemaId { + if (!this.#schemaId) { + throw new Error( + 'Configure a schema id with `session.schemaId()` or with the `options` ' + + 'parameter on methods.', + ); + } + + return this.#schemaId; + } + + /** + * Set a schema id for this whole session. + * + * This value will be used if no other schema id is defined through a methods + * `options` parameter. + * + * @param id - schema id + * @returns Session instance + */ + setSchemaId(id: SchemaId): Session { + this.#schemaId = id; + return this; + } + + /** + * Globally configured key pair which is used as a default for all requests. + */ + #keyPair: KeyPair | null = null; + + /** + * Returns currently configured key pair. + * + * Throws if no key pair is configured. + * + * @returns KeyPair instance + */ + get keyPair(): KeyPair { + if (!this.#keyPair) { + throw new Error( + 'Configure a key pair with `session.keyPair()` or with the `options` ' + + 'parameter on methods.', + ); + } + + return this.#keyPair; + } + + /** + * Set a fixed key pair for this session, which will be used by methods + * unless a different key pair is configured through their `options` + * parameters. + * + * This does not check the integrity or type of the supplied key pair! + * + * @param keyPair - key pair instance generated using the `KeyPair` class. + * @returns Session instance + */ + setKeyPair(keyPair: KeyPair): Session { + this.#keyPair = keyPair; + return this; + } + + /** + * Return arguments for constructing the next entry given public key and + * document view id. + * + * @param publicKey - public key of the author + * @param viewId - optional document view id + * @returns NextArgs arguments used to create a new entry + */ + async nextArgs( + publicKey: PublicKey, + viewId?: DocumentViewId, + ): Promise { + if (!publicKey) { + throw new Error("Author's public key must be provided"); + } + + const result = await nextArgs(this.client, { + publicKey, + viewId, + }); + + return result; + } + + /** + * Publish an encoded entry and operation. + * + * This method returns the "local" document view id, which represents the + * latest version of the document we've created, updated or deleted. + * + * It is "local" because it is the "latest version" from our perspective. + * Concurrent updates through other peers might have happend but we didn't + * know about them in the moment we've published our operation. + * + * If concurrent edits by other peers should also be referred to (as is + * often the case) then the document view id should be accessed via the + * GraphQL client API. + * + * @param entry - encoded and signed entry, represented as hexadecimal + * string + * @param operation - encoded CBOR operation, represented as hexadecimal + * string + * @returns DocumentViewId - local document view id + */ + async publish( + entry: EncodedEntry, + operation: EncodedOperation, + ): Promise { + if (!entry || !operation) { + throw new Error('Encoded entry and operation must be provided'); + } + + // Publish entry with operation payload and retreive next entry arguments + // for future updates on that document + await publish(this.client, { entry, operation }); + const localViewId = generateHash(entry); + + // Return document view id of the "latest" version from our perspective, + // hence "local" + return localViewId; + } + + /** + * Creates a new document with the given fields and matching schema id. + * + * @param fields - application data to publish with the new entry, needs to + * match schema + * @param options - overrides globally set options for this method call + * @param options.keyPair - will be used to sign the new entry + * @param options.schemaId - will be used as the matching schema identifier + * @returns Document id of the document we've created + * @example + * ``` + * const endpoint = 'http://localhost:2020/graphql'; + * const keyPair = new KeyPair(); + * const schemaId = 'chat_00206394434d78553bd064c8ea9a61d2b9622826909966ae895eb1c8b692b335d919'; + * + * const fields = { + * message: 'ahoy' + * }; + * + * await new Session(endpoint) + * .setKeyPair(keyPair) + * .create(fields, { schemaId }); + * ``` + */ + async create( + fields: Fields, + options?: Partial, + ): Promise { + if (!fields) { + throw new Error('Fields must be provided'); + } + + const schemaId = options?.schemaId || this.schemaId; + const keyPair = options?.keyPair || this.keyPair; + + // Retreive next entry arguments + const publicKey = keyPair.publicKey(); + const nextArgs = await this.nextArgs(publicKey); + + // Sign and encode entry with CREATE operation + const { entry, operation } = createOperation( + { + schemaId, + fields, + }, + { + keyPair, + nextArgs, + }, + ); + + // Publish entry and operation on node, return the "local" document view id + // which in this case will be the id of the document we've just created + const localViewId = await this.publish(entry, operation); + return localViewId; + } + + /** + * Updates a document with the given fields and matching schema id. + * + * The document to be updated is identified by the `previous` parameter which contains + * the most recent known document view id. + * + * @param fields - data to publish with the new entry, needs to match schema + * @param previous - array or string of operation ids identifying the tips of + * all currently un-merged branches in the document graph + * @param options - overrides globally set options for this method call + * @param options.keyPair - will be used to sign the new entry + * @param options.schemaId - will be used as the matching schema identifier + * @returns Document view id, pointing at the exact version of the document + * we've just updated + * @example + * ``` + * const endpoint = 'http://localhost:2020/graphql'; + * const keyPair = new KeyPair(); + * const schemaId = 'chat_00206394434d78553bd064c8ea9a61d2b9622826909966ae895eb1c8b692b335d919'; + * + * const session = new Session(endpoint) + * .setKeyPair(keyPair) + * .setSchemaId(schemaId); + * + * // Create a new document first + * const viewId = await session.create({ + * message: 'ahoy!' + * }); + * + * // Use the `viewId` to point our update at the document we've just created + * await session.update({ + * message: 'ahoy, my friend!' + * }, viewId); + * ``` + */ + async update( + fields: Fields, + previous: DocumentViewId, + options?: Partial, + ): Promise { + if (!fields) { + throw new Error('Fields must be provided'); + } + + if (!previous) { + throw new Error('Document view id must be provided'); + } + + const schemaId = options?.schemaId || this.schemaId; + const keyPair = options?.keyPair || this.keyPair; + + // Retreive next entry arguments + const publicKey = keyPair.publicKey(); + const nextArgs = await this.nextArgs(publicKey); + + // Sign and encode entry with UPDATE operation + const { entry, operation } = updateOperation( + { + schemaId, + previous, + fields, + }, + { + keyPair, + nextArgs, + }, + ); + + // Publish entry and operation on node, return the "local" document view id + // which in this case will be the id of the update we've just made + const localViewId = await this.publish(entry, operation); + return localViewId; + } + + /** + * Deletes a document. + * + * The document to be deleted is identified by the `previous` parameter + * which contains the most recent known document view id. + * + * @param previous - array or string of operation ids identifying the tips of + * all currently un-merged branches in the document graph + * @param options - overrides globally set options for this method call + * @param options.keyPair - will be used to sign the new entry + * @param options.schemaId - will be used as the matching schema identifier + * @returns Document view id, pointing at the exact version of the document + * we've just deleted + * @example + * ``` + * const endpoint = 'http://localhost:2020/graphql'; + * const keyPair = new KeyPair(); + * const schemaId = 'chat_00206394434d78553bd064c8ea9a61d2b9622826909966ae895eb1c8b692b335d919'; + * + * const session = new Session(endpoint) + * .setKeyPair(keyPair) + * .setSchemaId(schemaId); + * + * // Create a new document first + * const viewId = await session.create({ + * message: 'ahoy!' + * }); + * + * // Use the `viewId` to point our deletion at the document we've just created + * await session.delete(viewId); + * ``` + */ + async delete( + previous: DocumentViewId, + options?: Partial, + ): Promise { + if (!previous) { + throw new Error('Document view id must be provided'); + } + + const schemaId = options?.schemaId || this.schemaId; + const keyPair = options?.keyPair || this.keyPair; + + // Retreive next entry arguments + const publicKey = keyPair.publicKey(); + const nextArgs = await this.nextArgs(publicKey); + + // Sign and encode entry with DELETE operation + const { entry, operation } = deleteOperation( + { + schemaId, + previous, + }, + { + keyPair, + nextArgs, + }, + ); + + // Publish entry and operation on node, return the "local" document view id + // which in this case will be the id of the deletion we've just made + const localViewId = await this.publish(entry, operation); + return localViewId; + } +} diff --git a/src/session/index.ts b/src/session/index.ts deleted file mode 100644 index 5a0b35a..0000000 --- a/src/session/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -export { Context, Session } from './session'; diff --git a/src/session/session.test.ts b/src/session/session.test.ts deleted file mode 100644 index bb192c2..0000000 --- a/src/session/session.test.ts +++ /dev/null @@ -1,272 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -/* eslint-disable @typescript-eslint/ban-ts-comment */ -import { GQL_NEXT_ARGS, GQL_PUBLISH } from './session'; -import { Session } from './'; -import { KeyPair } from '../identity'; - -import type { Fields } from '../types'; -import type { FetchMockStatic } from 'fetch-mock'; - -import { - authorFixture, - documentIdFixture, - encodedEntryFixture, - entryArgsFixture, - entryFixture, - schemaFixture, -} from '../../test/fixtures'; - -/* Set up GraphQL server mock. It will respond to: - * - query `nextArgs`: always returns entry args for sequence number 6 - * - mutation `publish` always returns a response as if sequence - * number 5 had been published. */ -// eslint-disable-next-line @typescript-eslint/no-var-requires -jest.mock('node-fetch', () => require('fetch-mock-jest').sandbox()); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const fetchMock: FetchMockStatic = require('node-fetch'); - -// @ts-ignore -fetchMock.config.matchPartialBody = true; - -fetchMock - .mock( - { - name: 'nextArgs', - url: 'http://localhost:2020', - body: { query: GQL_NEXT_ARGS }, - }, - { - data: { - nextArgs: entryArgsFixture(5), - }, - }, - ) - .mock( - { - name: 'publish', - url: 'http://localhost:2020', - body: { query: GQL_PUBLISH }, - }, - { - data: { - publish: entryArgsFixture(5), - }, - }, - ); - -/** - * Test the `Session` class. - * - * These tests expect the mock rpc server to be running, which can be started - * with `npm run test:mock-node`. - */ -describe('Session', () => { - let keyPair: KeyPair; - - beforeAll(() => { - keyPair = new KeyPair(authorFixture().privateKey); - }); - - it('requires an endpoint parameter', () => { - expect(() => { - // @ts-ignore: We deliberately use the API wrong here - new Session(); - }).toThrow('Missing `endpoint` parameter for creating a session'); - - expect(() => { - new Session(''); - }).toThrow('Missing `endpoint` parameter for creating a session'); - }); - - it('has a string representation', async () => { - const session = new Session('http://localhost:2020'); - expect(`${session}`).toEqual(''); - - session.setKeyPair(keyPair); - expect(`${session}`).toMatch( - //, - ); - - session.setSchema(schemaFixture()); - expect(`${session}`).toMatch( - //, - ); - }); - - describe('publish', () => { - it('can publish entries', async () => { - const session = new Session('http://localhost:2020'); - - try { - const nextArgs = await session.publish( - encodedEntryFixture(4).entryBytes, - encodedEntryFixture(4).payloadBytes, - ); - expect(nextArgs.backlink).toEqual(entryArgsFixture(5).backlink); - } catch (err) { - console.error(err); - throw err; - } - }); - - it('throws when publishing without all required parameters', async () => { - const session = new Session('http://localhost:2020'); - await expect( - // @ts-ignore: We deliberately use the API wrong here - session.publish(null, encodedEntryFixture(1).payloadBytes), - ).rejects.toThrow(); - await expect( - // @ts-ignore: We deliberately use the API wrong here - session.publish(encodedEntryFixture(1).entryBytes, null), - ).rejects.toThrow(); - }); - }); - - describe('get/setnextArgs', () => { - it('returns next entry args from node', async () => { - const session = new Session('http://localhost:2020'); - - const nextArgs = await session.getNextArgs( - authorFixture().publicKey, - documentIdFixture(), - ); - expect(nextArgs.skiplink).toEqual(entryArgsFixture(5).skiplink); - expect(nextArgs.backlink).toEqual(entryArgsFixture(5).backlink); - expect(nextArgs.seqNum).toEqual(entryArgsFixture(5).seqNum); - expect(nextArgs.logId).toEqual(entryArgsFixture(5).logId); - }); - - it('returns next entry args from cache', async () => { - const session = new Session('http://localhost:2020'); - - // Add a spy to check whether the value is really retrieved from the - // cache and not requested - const mockedFn = jest.fn(async () => true); - // @ts-ignore Yes, Typescript, a mock is not the same as the original. - session.client.query = mockedFn; - - const nextArgs = { - // Treat json `null` as undefined - backlink: entryArgsFixture(5).backlink as string | undefined, - skiplink: entryArgsFixture(5).skiplink as string | undefined, - logId: entryArgsFixture(5).logId, - seqNum: entryArgsFixture(5).seqNum, - }; - session.setNextArgs( - authorFixture().publicKey, - documentIdFixture(), - nextArgs, - ); - - const cacheResponse = await session.getNextArgs( - authorFixture().publicKey, - documentIdFixture(), - ); - expect(cacheResponse.logId).toEqual(nextArgs.logId); - expect(mockedFn.mock.calls.length).toBe(0); - }); - }); - - describe('create', () => { - let session: Session; - - // Fields for document to be created - const fields = entryFixture(1).operation?.fields as Fields; - - beforeEach(async () => { - session = new Session('http://localhost:2020'); - session.setKeyPair(keyPair); - }); - - it('handles valid arguments', async () => { - jest.spyOn(session, 'getNextArgs').mockResolvedValue(entryArgsFixture(1)); - - expect( - await session.create(fields, { - schema: schemaFixture(), - }), - ).resolves; - expect(await session.setSchema(schemaFixture()).create(fields)).resolves; - }); - - it('throws when missing a required parameter', async () => { - await expect( - // @ts-ignore: We deliberately use the API wrong here - session.setKeyPair(keyPair).create(), - ).rejects.toThrow(); - }); - }); - - describe('update', () => { - let session: Session; - - // These are the fields for an update operation - const fields = entryFixture(2).operation?.fields as Fields; - - // These are the previous operations - const previous = entryFixture(2).operation?.previous as string[]; - - beforeEach(async () => { - session = new Session('http://localhost:2020'); - session.setKeyPair(keyPair); - jest.spyOn(session, 'getNextArgs').mockResolvedValue(entryArgsFixture(2)); - }); - - it('handles valid arguments', async () => { - expect( - await session.update(fields, previous, { - schema: schemaFixture(), - }), - ).resolves; - - expect(await session.setSchema(schemaFixture()).update(fields, previous)) - .resolves; - }); - - it('throws when missing a required parameter', async () => { - await expect( - // @ts-ignore: We deliberately use the API wrong here - session.update(null, { schema: schemaFixture() }), - ).rejects.toThrow(); - await expect( - // @ts-ignore: We deliberately use the API wrong here - session.update(fields), - ).rejects.toThrow(); - }); - }); - - describe('delete', () => { - let session: Session; - - // These are the previous operations - const previous = entryFixture(2).operation?.previous as string[]; - - beforeEach(async () => { - session = new Session('http://localhost:2020'); - session.setKeyPair(keyPair); - jest.spyOn(session, 'getNextArgs').mockResolvedValue(entryArgsFixture(3)); - }); - - it('handles valid arguments', async () => { - expect( - session.delete(previous, { - schema: schemaFixture(), - }), - ).resolves; - expect(session.setSchema(schemaFixture()).delete(previous)).resolves; - }); - - it('throws when missing a required parameter', async () => { - expect( - // @ts-ignore: We deliberately use the API wrong here - session.delete(null, { schema: schemaFixture() }), - ).rejects.toThrow(); - - expect( - // @ts-ignore: We deliberately use the API wrong here - session.delete(previous), - ).rejects.toThrow(); - }); - }); -}); diff --git a/src/session/session.ts b/src/session/session.ts deleted file mode 100644 index f76e08e..0000000 --- a/src/session/session.ts +++ /dev/null @@ -1,365 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -import debug from 'debug'; -import { gql, GraphQLClient } from 'graphql-request'; - -import { createDocument, deleteDocument, updateDocument } from '../document'; - -import type { KeyPair } from 'p2panda-js'; -import type { NextArgs, Fields, SchemaId } from '../types'; - -const log = debug('shirokuma:session'); - -export type Context = { - keyPair: KeyPair; - schema: SchemaId; - session: Session; -}; - -type NextArgsVariables = { - publicKey: string; - viewId?: string; -}; - -// GraphQL query to retrieve next entry args from node. -export const GQL_NEXT_ARGS = gql` - query NextArgs($publicKey: String!, $viewId: String) { - nextArgs(publicKey: $publicKey, viewId: $viewId) { - logId - seqNum - backlink - skiplink - } - } -`; - -type PublishVariables = { - entry: string; - operation: string; -}; - -// GraphQL mutation to publish an entry and retrieve arguments for encoding the -// next operation on the same document (those are currently not used to update -// the next entry arguments cache). -export const GQL_PUBLISH = gql` - mutation Publish($entry: String!, $operation: String!) { - publish(entry: $entry, operation: $operation) { - logId - seqNum - backlink - skiplink - } - } -`; - -/** - * Communicate with the p2panda network through a `Session` instance. - * - * `Session` provides a high-level interface to create data in the p2panda - * network by creating, updating and deleting documents following data schemas. - * It also provides a low-level API for directly accessing and creating - * entries on the Bamboo append-only log structure. - * - * A session is configured with the URL of a p2panda node, which may be running - * locally or on a remote machine. It is possible to set a fixed key pair - * and/or data schema for a session by calling `setKeyPair()` and `setSchema()` - * or you can also configure these through the `options` parameter of - * methods. - */ -export class Session { - // Address of a p2panda node that we can connect to - endpoint: string; - - // A GraphQL client connected to the configured endpoint - client: GraphQLClient; - - // Cached arguments for the next entry - private nextArgs: { [cacheKey: string]: NextArgs } = {}; - - constructor(endpoint: Session['endpoint']) { - if (endpoint == null || endpoint === '') { - throw new Error('Missing `endpoint` parameter for creating a session'); - } - this.endpoint = endpoint; - this.client = new GraphQLClient(endpoint); - } - - private _schema: SchemaId | null = null; - - /** - * Return currently configured schema. - * - * Throws if no schema is configured. - */ - get schema(): SchemaId { - if (!this._schema) { - throw new Error( - 'Configure a schema with `session.schema()` or with the `options` ' + - 'parameter on methods.', - ); - } - return this._schema; - } - - /** - * Set a fixed schema for this session, which will be used if no other schema - * is defined through a methods `options` parameter. - * - * @param val schema id - * @returns Session - */ - setSchema(val: SchemaId): Session { - this._schema = val; - return this; - } - - private _keyPair: KeyPair | null = null; - - get keyPair(): KeyPair { - if (!this._keyPair) { - throw new Error( - 'Configure a key pair with `session.keyPair()` or with the `options` ' + - 'parameter on methods.', - ); - } - return this._keyPair; - } - - /** - * Set a fixed key pair for this session, which will be used by methods - * unless a different key pair is configured through their `options` - * parameters. - * - * This does not check the integrity or type of the supplied key pair! - * - * @param val key pair instance generated using the `KeyPair` class. - * @returns key pair instance - */ - setKeyPair(val: KeyPair): Session { - this._keyPair = val; - return this; - } - - /** - * Return arguments for constructing the next entry given author and schema. - * - * This uses the cache set through `Session._setnextArgs`. - * - * @param publicKey public key of the author - * @param viewId optional document view id - * @returns an `EntryArgs` object - */ - async getNextArgs(publicKey: string, viewId?: string): Promise { - if (!publicKey) { - throw new Error("Author's public key must be provided"); - } - - const variables: NextArgsVariables = { - publicKey, - }; - - // Use cache only when viewId is set - if (viewId) { - const cacheKey = `${publicKey}/${viewId}`; - const cachedValue = this.nextArgs[cacheKey]; - - if (cachedValue) { - delete this.nextArgs[cacheKey]; - log('request nextArgs [cached]', cachedValue); - return cachedValue; - } - - variables.viewId = viewId; - } - - try { - const data = await this.client.request(GQL_NEXT_ARGS, variables); - // @TODO: Query `nextArgs` is deprecated and will be replaced by `nextArgs` soon - const nextArgs = data.nextArgs; - log('request nextArgs', nextArgs); - return nextArgs; - } catch (err) { - log('Error fetching nextArgs'); - throw err; - } - } - - /** - * Cache next entry args for a given author and document id. - * - * @param publicKey public key of the author - * @param viewId document id - * @param nextArgs an object with entry arguments - */ - setNextArgs(publicKey: string, viewId: string, nextArgs: NextArgs): void { - const cacheKey = `${publicKey}/${viewId}`; - this.nextArgs[cacheKey] = nextArgs; - } - - /** - * Publish an encoded entry and operation. - * - * @param entry - * @param operation - * @returns next entry arguments - */ - async publish(entry: string, operation: string): Promise { - if (!entry || !operation) { - throw new Error('Encoded entry and operation must be provided'); - } - - const variables: PublishVariables = { - entry, - operation, - }; - - try { - const data = await this.client.request(GQL_PUBLISH, variables); - log('request publish', data); - // @TODO: Query `publish` is deprecated and will be replaced by `publish` soon - if (data?.publish == null) { - throw new Error("Response doesn't contain field `publish`"); - } - return data.publish; - } catch (err) { - log('Error publishing entry'); - throw err; - } - } - - // Document operations - - /** - * Signs and publishes a CREATE operation for the given application data and - * matching schema. - * - * Caches arguments for creating the next entry of this document in the given - * session. - * - * @param fields application data to publish with the new entry, needs to match schema - * @param options optional config object: - * @param options.keyPair will be used to sign the new entry - * @param options.schema hex-encoded schema id - * @example - * const operationFields = { - * message: 'ahoy' - * }; - * await new Session(endpoint) - * .setKeyPair(keyPair) - * .create(operationFields, { schema }); - */ - async create(fields: Fields, options?: Partial): Promise { - // We should validate the data against the schema here too eventually - if (!fields) { - throw new Error('Operation fields must be provided'); - } - - log('create document', fields); - const mergedOptions = { - schema: options?.schema || this.schema, - keyPair: options?.keyPair || this.keyPair, - session: this, - }; - createDocument(fields, mergedOptions); - - return this; - } - - /** - * Signs and publishes an UPDATE operation for the given application data and - * matching schema. - * - * The document to be updated is identified by the `previous` parameter which contains - * the most recent known document view id. - * - * Caches arguments for creating the next entry of this schema in the given - * session. - * - * @param fields application data to publish with the new entry, needs to match schema - * @param previous array of operation ids identifying the tips of all currently un-merged branches in the document graph - * @param options optional config object: - * @param options.keyPair will be used to sign the new entry - * @param options.schema hex-encoded schema id - * @example - * const operationFields = { - * message: 'ahoy', - * }; - * const previous = [ - * '00203341c9dd226525886ee77c95127cd12f74366703e02f9b48f3561a9866270f07', - * ]; - * await new Session(endpoint) - * .setKeyPair(keyPair) - * .update(operationFields, previous, { schema }); - */ - async update( - fields: Fields, - previous: string[], - options?: Partial, - ): Promise { - // We should validate the data against the schema here too eventually - if (!previous) { - throw new Error('Previous view id must be provided'); - } - - if (!fields) { - throw new Error('Operation fields must be provided'); - } - - log('update document wyth view ', previous, fields); - const mergedOptions = { - schema: options?.schema || this.schema, - keyPair: options?.keyPair || this.keyPair, - session: this, - }; - updateDocument(previous, fields, mergedOptions); - - return this; - } - - /** - * Signs and publishes a DELETE operation for the given schema. - * - * The document to be deleted is identified by the `previous` parameter - * which contains the most recent known document view id. - * - * Caches arguments for creating the next entry of this schema in the given session. - * - * @param previous array of operation ids identifying the tips of all currently un-merged branches in the document graph - * @param options optional config object: - * @param options.keyPair will be used to sign the new entry - * @param options.schema hex-encoded schema id - * @example - * const previous = [ - * '00203341c9dd226525886ee77c95127cd12f74366703e02f9b48f3561a9866270f07', - * ]; - * await new Session(endpoint) - * .setKeyPair(keyPair) - * .delete(previous, { schema }); - */ - async delete( - previous: string[], - options?: Partial, - ): Promise { - if (!previous) { - throw new Error('Previous view id must be provided'); - } - - log('delete document with view ', previous); - const mergedOptions = { - schema: options?.schema || this.schema, - keyPair: options?.keyPair || this.keyPair, - session: this, - }; - deleteDocument(previous, mergedOptions); - - return this; - } - - toString(): string { - const keyPairStr = this._keyPair - ? ` key pair ${this._keyPair.publicKey().slice(-8)}` - : ''; - const schemaStr = this._schema ? ` schema ${this.schema.slice(-8)}` : ''; - return ``; - } -} diff --git a/src/types.ts b/src/types.ts index 4d63d2b..f282cba 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,181 +1,115 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -export type SchemaId = - | 'schema_definition_v1' - | 'schema_field_definition_v1' - | string; +import type { EasyValues, KeyPair, OperationFields } from 'p2panda-js'; /** - * Arguments for publishing the next entry. + * Ed25519 public key of author. */ -export type NextArgs = { - skiplink: string | undefined; - backlink: string | undefined; - seqNum: string; - logId: string; -}; +export type PublicKey = string; /** - * Entry record received from aquadoggo. + * YASMF-BLAKE3 hash of an Bamboo entry. */ -export type EncodedEntry = { - author: string; - entryBytes: string; - entryHash: string; - logId: bigint; - payloadBytes: string; - payloadHash: string; - seqNum: bigint; -}; +export type EntryHash = string; /** - * Entry record from aquadoggo with decoded `Entry`. + * Document view id which contains one to many operation ids, either as one + * string separated by underscores or as an array of strings. */ -export type EntryRecord = Entry & { - encoded: EncodedEntry; -}; +export type DocumentViewId = string | string[]; /** - * Decoded entry containing optional `Operation`. + * Application- (custom) or System schema (constant) identifier. */ -export type Entry = { - backlink: string | undefined; - skiplink: string | undefined; - logId: bigint; - operation: Operation | undefined; - seqNum: bigint; -}; +export type SchemaId = + | 'schema_definition_v1' + | 'schema_field_definition_v1' + | string; /** - * Decoded form of an operation, which can create, update or delete documents. + * Data fields sent within an operation. */ -export type Operation = { - action: 'create' | 'update' | 'delete'; - schema: SchemaId; - previous?: string[]; - fields?: Fields; - id?: string; -}; +export type Fields = EasyValues | OperationFields; /** - * Object containing operation field values. + * Arguments required to create a new document. */ -export type Fields = { - [fieldname: string]: - | boolean - | number - | string - | bigint - | Relation - | Relation[] - | PinnedRelation - | PinnedRelation[]; +export type CreateArgs = { + schemaId: SchemaId; + fields: Fields; }; /** - * Relation pointing at a document id. + * Arguments required to update a new document. */ -export type Relation = string; - -/** - * Pinned relation pointing at a document view id. - */ -export type PinnedRelation = string[]; - -/** - * Decoded entry containing optional `Operation`. - */ -export type EntryTagged = { - backlink: string | undefined; - skiplink: string | undefined; - logId: bigint; - operation: OperationTagged | undefined; - seqNum: bigint; +export type UpdateArgs = { + schemaId: SchemaId; + previous: DocumentViewId; + fields: Fields; }; /** - * Decoded form of an operation, which can create, update or delete documents. + * Arguments required to delete a new document. */ -export type OperationTagged = { - action: 'create' | 'update' | 'delete'; - previous?: string[]; - schema: SchemaId; - fields: FieldsTagged; +export type DeleteArgs = { + schemaId: SchemaId; + previous: DocumentViewId; }; /** - * Object containing operation fields in tagged form. - */ -export type FieldsTagged = Map; - -export type OperationValue = - | OperationValueBool - | OperationValueFloat - | OperationValueInt - | OperationValueRelation - | OperationValueRelationList - | OperationValueText; - -/** - * An operation value of `boolean` type. + * Arguments required to create and sign a new Bamboo entry. */ -export type OperationValueBool = { - value: boolean; - type: 'bool'; +export type EntryArgs = { + keyPair: KeyPair; + nextArgs: NextArgs; }; /** - * An operation value of `integer` type. + * Response data from `nextArgs` and `publish` GraphQL query. Contains all the + * important bits to create a new Bamboo entry. */ -export type OperationValueInt = { - // Internally stored as a string to give support for very large numbers - value: string; - type: 'int'; +export type NextArgs = { + skiplink?: string; + backlink?: string; + seqNum: string | bigint | number; + logId: string | bigint | number; }; /** - * An operation value of `float` type. + * Bamboo entry bytes, encoded as hexadecimal string. */ -export type OperationValueFloat = { - value: number; - type: 'float'; -}; +export type EncodedEntry = string; /** - * An operation value of `string` type. + * CBOR operation bytes, encoded as hexadecimal string. */ -export type OperationValueText = { - value: string; - type: 'str'; -}; +export type EncodedOperation = string; /** - * An operation value of `relation` type. + * To-be-published entry and operation data. */ -export type OperationValueRelation = { - value: Relation; - type: 'relation'; +export type Payload = { + entry: EncodedEntry; + operation: EncodedOperation; }; /** - * An operation value of `relation_list` type. + * To-be-published entry and operation data plus additional information about + * the current, local document view id */ -export type OperationValueRelationList = { - value: Relation[]; - type: 'relation_list'; +export type PayloadWithViewId = Payload & { + localViewId: EntryHash; }; + /** - * An operation value of `pinned_relation` type. + * Request data for `nextArgs` GraphQL query. */ -export type OperationValuePinnedRelation = { - value: PinnedRelation; - type: 'pinned_relation'; +export type NextArgsVariables = { + publicKey: PublicKey; + viewId?: DocumentViewId; }; /** - * An operation value of `pinned_relation_list` type. + * Request data for `publish` GraphQL mutation. */ -export type OperationValuePinnedRelationList = { - value: PinnedRelation[]; - type: 'pinned_relation_list'; -}; +export type PublishVariables = Payload; diff --git a/src/utils.test.ts b/src/utils.test.ts deleted file mode 100644 index 2b0026c..0000000 --- a/src/utils.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -/* eslint-disable @typescript-eslint/ban-ts-comment */ - -import { marshallRequestFields, marshallResponseFields } from './utils'; -import { Fields, FieldsTagged } from './types'; - -const REQUEST: Fields = { - channel: 5, - operation: 'chin chin', - serious: false, - temperature: 19.5, -}; - -const RESPONSE: FieldsTagged = new Map(); - -RESPONSE.set('channel', { - value: '5', - type: 'int', -}); - -RESPONSE.set('operation', { - value: 'chin chin', - type: 'str', -}); - -RESPONSE.set('serious', { - value: false, - type: 'bool', -}); - -RESPONSE.set('temperature', { - value: 19.5, - type: 'float', -}); - -const LARGE_NUMBER_REQUEST: Fields = { - largeNumber: BigInt('894328732428428423810'), -}; - -const LARGE_NUMBER_RESPONSE: FieldsTagged = new Map(); - -LARGE_NUMBER_RESPONSE.set('largeNumber', { - value: '894328732428428423810', - type: 'int', -}); - -describe('Utils', () => { - describe('marshallRequestFields', () => { - it("creates aquadoggo's expected request format", () => { - expect(marshallRequestFields(REQUEST)).toEqual(RESPONSE); - - // Large number passed as 'BigInt' will be converted to 'int' type - expect(marshallRequestFields(LARGE_NUMBER_REQUEST)).toEqual( - LARGE_NUMBER_RESPONSE, - ); - }); - - it('ignores undefined fields', () => { - const request: Fields = { - channel: 5, - // @ts-ignore - username: undefined, - }; - - const result = marshallRequestFields(request); - expect(result.size).toBe(1); - }); - }); - - describe('marshallResponseFields', () => { - it("handles aquadoggo's response format", () => { - expect(marshallResponseFields(RESPONSE)).toEqual(REQUEST); - - // Large numbers will be returned as strings - expect(marshallResponseFields(LARGE_NUMBER_RESPONSE)).toEqual({ - largeNumber: LARGE_NUMBER_REQUEST.largeNumber.toString(), - }); - }); - }); -}); diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 04724dd..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,105 +0,0 @@ -import type { Fields, FieldsTagged } from './types'; - -const FIELD_TYPE_MAPPING = { - bigint: 'int', - boolean: 'bool', - number: 'int', - string: 'str', -}; - -/** - * Look up the type of a schema's fields. - * - * While we don't have proper schema support in the node this function just - * guesses the schema's field type from a supplied fields record. - * - * Returns null when a key has no value. - * - * @param fields assumed to be correct operation fields for an instance - * @param key name of the field for which to look up the type - * @returns field type - */ -const getFieldType = ( - fields: Fields, - key: string, -): 'str' | 'bool' | 'int' | null => { - const type = typeof fields[key]; - - if (type === 'undefined') { - // Return null if a key has no value - return null; - } - - if (!Object.keys(FIELD_TYPE_MAPPING).includes(type)) { - throw new Error(`Unsupported field type: ${type}`); - } - - // @ts-expect-error we have made sure that `type` is a key of `mapping` - return FIELD_TYPE_MAPPING[type]; -}; - -/** - * Add type tags to operation fields before sending to node. - */ -export const marshallRequestFields = (fields: Fields): FieldsTagged => { - const map: FieldsTagged = new Map(); - - Object.keys(fields).forEach((key) => { - const value = fields[key]; - - switch (getFieldType(fields, key)) { - case 'str': - map.set(key, { value: value as string, type: 'str' }); - break; - case 'int': - // "int" can be a BigInt instance or "number" which again can be a - // float or integer type in the JavaScript world - if (typeof value === 'number' && value.toString().includes('.')) { - // This is a float number - map.set(key, { - value: value as number, - type: 'float', - }); - } else if (typeof value === 'bigint') { - // Convert bigints into strings and store as "int" - map.set(key, { value: value.toString(), type: 'int' }); - } else { - // This is a regular integer, convert it to string and store as "int" - map.set(key, { - value: (value as number).toString(), - type: 'int', - }); - } - - break; - case 'bool': - map.set(key, { value: value as boolean, type: 'bool' }); - break; - case null: - // Skip fields that have no value - break; - } - }); - - return map; -}; - -/** - * Remove type tags from operation fields on an entry received from node. - */ -export const marshallResponseFields = (fieldsTagged: FieldsTagged): Fields => { - const fields: Fields = {}; - - for (const [key, fieldValue] of fieldsTagged.entries()) { - const { type, value } = fieldValue; - - // Convert smaller integers to 'number', keep large ones as strings - if (type === 'int' && BigInt(value as string) <= Number.MAX_SAFE_INTEGER) { - fields[key] = parseInt(value as string, 10); - } else { - fields[key] = value; - } - } - - return fields; -}; diff --git a/test/fixtures.json b/test/fixtures.json new file mode 100644 index 0000000..e7d2886 --- /dev/null +++ b/test/fixtures.json @@ -0,0 +1,107 @@ +{ + "entries": [ + { + "encodedEntry": "00b8556f266f2f05df21f4f633d0498bf3dfbb79cad3453367c3002725b1a88fd800016e0020b7c3bb56feeaef9e1d9b6f231bc1fb0eee23b3c489d02fc1df71574561e01189789e3be9455fd2a5e128e2f9c216070ee1fba1e8f8f08ccbe1d1eab19f90eb7b213bdade3173ba8592a7c5b471a7af596678fc0b7cc2a9699da34219d539c709", + "entryHash": "0020e5350b648e798644f6f359976646a19defc3aa7f2ceecf9a675383b13d115388", + "encodedOperation": "8401007849636861745f3030323062633837346334303161643539383336346265383064313863613565636632663865393764306362353737343533386636326136663038633162346663653534a1676d657373616765764f68682c206d79206669727374206d65737361676521", + "logId": "0", + "seqNum": "1" + }, + { + "encodedEntry": "00b8556f266f2f05df21f4f633d0498bf3dfbb79cad3453367c3002725b1a88fd800020020e5350b648e798644f6f359976646a19defc3aa7f2ceecf9a675383b13d115388b10020a6c86e69c08d38e4771fa7d2c12320f76e5ac5184324f2157eb878f482c1abe42899f159fad3edf41d63185ff4bdc173d5238e88779e6c8d26629f2f77f1121450541f019d63205e75d3a110f51df0d6494970769f6ee15a32dceee267ba3907", + "entryHash": "0020fc8651a455cf0cfd30b1e6908a7faaffafe135a1e9ce39ad3ff58aff60461c40", + "encodedOperation": "8501017849636861745f30303230626338373463343031616435393833363462653830643138636135656366326638653937643063623537373435333866363261366630386331623466636535348178443030323065353335306236343865373938363434663666333539393736363436613139646566633361613766326365656366396136373533383362313364313135333838a1676d6573736167657257686963682049206e6f7720757064617465", + "logId": "0", + "seqNum": "2" + }, + { + "encodedEntry": "00b8556f266f2f05df21f4f633d0498bf3dfbb79cad3453367c3002725b1a88fd800030020fc8651a455cf0cfd30b1e6908a7faaffafe135a1e9ce39ad3ff58aff60461c40b4002006a46121eca22ad3c2e8a4c264877006bac07cee781b1a71f0a11aaa411e5c9aacf075898a7d7f4168653dbec188dceaa5fce30f7eb490a632fd5f4a097fa8a5018da667757e43407555928de29f65ae169ce44ca77c7a04fa2982050e96e806", + "entryHash": "0020a5251c61b7798cf820c237e291b2a35fae5655e582599628be1cadc343ad3a10", + "encodedOperation": "8501017849636861745f30303230626338373463343031616435393833363462653830643138636135656366326638653937643063623537373435333866363261366630386331623466636535348178443030323066633836353161343535636630636664333062316536393038613766616166666166653133356131653963653339616433666635386166663630343631633430a1676d65737361676575416e64207468656e2075706461746520616761696e", + "logId": "0", + "seqNum": "3" + }, + { + "encodedEntry": "00b8556f266f2f05df21f4f633d0498bf3dfbb79cad3453367c3002725b1a88fd800040020e5350b648e798644f6f359976646a19defc3aa7f2ceecf9a675383b13d1153880020a5251c61b7798cf820c237e291b2a35fae5655e582599628be1cadc343ad3a109500205d6b1e8dd1c55c65c1942105a7dcc262b65e7bbe91b7de373a46d3515f5fb5ec8dca7968b179216df1d889af3ad90b609c1b27979fd5b7fa463358d1fa9a9287d34462c035e807be047c2aca3bdec8f8c4433cec8dc3739bafc33367e49d3502", + "entryHash": "0020f27fb00e940cd2baaeccf092e358a10d46c91ade0e34199db56c5d961c145af4", + "encodedOperation": "8401027849636861745f30303230626338373463343031616435393833363462653830643138636135656366326638653937643063623537373435333866363261366630386331623466636535348178443030323061353235316336316237373938636638323063323337653239316232613335666165353635356535383235393936323862653163616463333433616433613130", + "logId": "0", + "seqNum": "4" + } + ], + "nextArgs": [ + { + "backlink": null, + "logId": "0", + "seqNum": "1", + "skiplink": null + }, + { + "backlink": "0020e5350b648e798644f6f359976646a19defc3aa7f2ceecf9a675383b13d115388", + "logId": "0", + "seqNum": "2", + "skiplink": null + }, + { + "backlink": "0020fc8651a455cf0cfd30b1e6908a7faaffafe135a1e9ce39ad3ff58aff60461c40", + "logId": "0", + "seqNum": "3", + "skiplink": null + }, + { + "backlink": "0020a5251c61b7798cf820c237e291b2a35fae5655e582599628be1cadc343ad3a10", + "logId": "0", + "seqNum": "4", + "skiplink": "0020e5350b648e798644f6f359976646a19defc3aa7f2ceecf9a675383b13d115388" + }, + { + "backlink": "0020f27fb00e940cd2baaeccf092e358a10d46c91ade0e34199db56c5d961c145af4", + "logId": "0", + "seqNum": "5", + "skiplink": null + } + ], + "operations": [ + { + "action": "create", + "fields": { + "message": "Ohh, my first message!" + }, + "schemaId": "chat_0020bc874c401ad598364be80d18ca5ecf2f8e97d0cb5774538f62a6f08c1b4fce54", + "version": 1 + }, + { + "action": "update", + "fields": { + "message": "Which I now update" + }, + "previous": [ + "0020e5350b648e798644f6f359976646a19defc3aa7f2ceecf9a675383b13d115388" + ], + "schemaId": "chat_0020bc874c401ad598364be80d18ca5ecf2f8e97d0cb5774538f62a6f08c1b4fce54", + "version": 1 + }, + { + "action": "update", + "fields": { + "message": "And then update again" + }, + "previous": [ + "0020fc8651a455cf0cfd30b1e6908a7faaffafe135a1e9ce39ad3ff58aff60461c40" + ], + "schemaId": "chat_0020bc874c401ad598364be80d18ca5ecf2f8e97d0cb5774538f62a6f08c1b4fce54", + "version": 1 + }, + { + "action": "delete", + "previous": [ + "0020a5251c61b7798cf820c237e291b2a35fae5655e582599628be1cadc343ad3a10" + ], + "schemaId": "chat_0020bc874c401ad598364be80d18ca5ecf2f8e97d0cb5774538f62a6f08c1b4fce54", + "version": 1 + } + ], + "privateKey": "80117cd1732b94fd897708d4826f1f6f8863efc3c70fdec4350541f00270eca0", + "publicKey": "b8556f266f2f05df21f4f633d0498bf3dfbb79cad3453367c3002725b1a88fd8", + "schemaId": "chat_0020bc874c401ad598364be80d18ca5ecf2f8e97d0cb5774538f62a6f08c1b4fce54" +} diff --git a/test/fixtures.ts b/test/fixtures.ts deleted file mode 100644 index b5736f0..0000000 --- a/test/fixtures.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { marshallResponseFields } from '../src/utils'; - -import type { - EncodedEntry, - Entry, - NextArgs, - FieldsTagged, - Operation, - OperationTagged, - OperationValue, - SchemaId, -} from '../src/types'; - -import TEST_DATA from './test-data.json'; - -// Right now we only have one author `panda` who only has one schema log. This -// could be expanded in the future. -const encodedEntries = TEST_DATA.panda.logs[0].encodedEntries; -const nextArgs = TEST_DATA.panda.logs[0].nextArgs; - -// Convert JSON-imported operations to use `Map`s instead of objects for -// reporesenting operation fields. -const decodedOperations = TEST_DATA.panda.logs[0].decodedOperations.map( - (operation) => { - if (operation.fields) { - const fields: FieldsTagged = new Map(); - - Object.entries(operation.fields).forEach(([key, value]) => { - // @TODO: This only works with strings currently, it needs refactoring - // as soon as we have schemas - fields.set(key, { - value, - type: 'str', - } as OperationValue); - }); - - // assert the type of the JSON-imported `fields` as `unknown` so that - // Typescript allows writing our new `Map`-based value to it - (operation.fields as unknown) = fields; - } - - // also asserting the type as unknown to be able to change it to the correct - // return value type - return operation as unknown as OperationTagged; - }, -); - -export const schemaFixture = (): SchemaId => { - return decodedOperations[0].schema; -}; - -export const documentIdFixture = (): string => { - return encodedEntries[0].entryHash; -}; - -/** - * Return an object with fields for an author's public and private key. - */ -export const authorFixture = (): { publicKey: string; privateKey: string } => { - const author = { - publicKey: TEST_DATA.panda.publicKey, - privateKey: TEST_DATA.panda.privateKey, - }; - return author; -}; - -/** - * Return an Entry given a sequence number in the testing log. - */ -export const entryFixture = (seqNum: number): Entry => { - const index = seqNum - 1; - - let fields = undefined; - if (decodedOperations[index].action !== 'delete') { - fields = marshallResponseFields( - decodedOperations[index].fields as FieldsTagged, - ); - } - - const operation: Operation = { - action: decodedOperations[index].action as Operation['action'], - schema: decodedOperations[index].schema, - fields: fields, - }; - - if (decodedOperations[index].previous) { - operation.previous = - decodedOperations[index].previous; - } - - const entry: Entry = { - backlink: nextArgs[index].backlink as string | undefined, - skiplink: nextArgs[index].skiplink as string | undefined, - seqNum: BigInt(nextArgs[index].seqNum), - logId: BigInt(nextArgs[index].logId), - operation, - }; - - return entry; -}; - -/** - * Return an encoded entry given a sequence number on the mock log. - */ -export const encodedEntryFixture = (seqNum: number): EncodedEntry => { - const index = seqNum - 1; - - const encodedEntry: EncodedEntry = { - author: TEST_DATA.panda.publicKey, - entryBytes: encodedEntries[index].entryBytes, - entryHash: encodedEntries[index].entryHash, - logId: BigInt(encodedEntries[index].logId), - payloadBytes: encodedEntries[index].payloadBytes, - payloadHash: encodedEntries[index].payloadHash, - seqNum: BigInt(encodedEntries[index].seqNum), - }; - - return encodedEntry; -}; - -/** - * Return arguments for creating an entry. - * - * Takes a `seqNum` parameter, which is the sequence number of - * the entry preceding the one we want arguments for. - */ -export const entryArgsFixture = (seqNum: number): NextArgs => { - const index = seqNum - 1; - - const entryArgs: NextArgs = { - backlink: (nextArgs[index].backlink || null) as string | undefined, - skiplink: (nextArgs[index].skiplink || null) as string | undefined, - seqNum: nextArgs[index].seqNum, - logId: nextArgs[index].logId, - }; - - return entryArgs; -}; diff --git a/test/session.test.ts b/test/session.test.ts new file mode 100644 index 0000000..e412836 --- /dev/null +++ b/test/session.test.ts @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +import fetchMockJest from 'fetch-mock-jest'; + +import fixtures from './fixtures.json'; + +import { Session, KeyPair } from '../src'; +import { GQL_PUBLISH, GQL_NEXT_ARGS } from '../src/graphql'; + +import type { Fields } from '../src/types'; +import type { FetchMockStatic } from 'fetch-mock'; + +/** + * Set up GraphQL server mock. It will respond to: + * - query `nextArgs`: always returns entry args for sequence number 6 + * - mutation `publish` always returns a response as if sequence number 5 had + * been published. + */ +jest.mock('node-fetch', () => fetchMockJest.sandbox()); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const fetchMock: FetchMockStatic = require('node-fetch'); + +// @ts-ignore +fetchMock.config.matchPartialBody = true; + +describe('Session', () => { + it('requires an endpoint parameter', () => { + expect(() => { + // @ts-ignore: We deliberately use the API wrong here + new Session(); + }).toThrow('Missing `endpoint` parameter for creating a session'); + + expect(() => { + new Session(''); + }).toThrow('Missing `endpoint` parameter for creating a session'); + }); +}); + +describe('nextArgs', () => { + beforeEach(() => { + fetchMock.mock( + { + name: 'nextArgs', + url: 'http://localhost:2020/graphql', + body: { + query: GQL_NEXT_ARGS, + variables: { + publicKey: fixtures.publicKey, + viewId: fixtures.entries[0].entryHash, + }, + }, + }, + { + data: { + nextArgs: fixtures.nextArgs[4], + }, + }, + ); + }); + + afterEach(() => { + // @ts-ignore + fetchMock.mockReset(); + }); + + it('returns next entry arguments from node', async () => { + const session = new Session('http://localhost:2020/graphql'); + + const nextArgs = await session.nextArgs( + fixtures.publicKey, + fixtures.entries[0].entryHash, + ); + const expectedArgs = fixtures.nextArgs[4]; + expect(nextArgs.skiplink).toEqual(expectedArgs.skiplink); + expect(nextArgs.backlink).toEqual(expectedArgs.backlink); + expect(nextArgs.seqNum).toEqual(expectedArgs.seqNum); + expect(nextArgs.logId).toEqual(expectedArgs.logId); + }); +}); + +describe('publish', () => { + beforeEach(() => { + fetchMock.mock( + { + name: 'publish', + url: 'http://localhost:2020/graphql', + body: { + query: GQL_PUBLISH, + variables: { + entry: fixtures.entries[3].encodedEntry, + operation: fixtures.entries[3].encodedOperation, + }, + }, + }, + { + data: { + nextArgs: fixtures.nextArgs[4], + }, + }, + ); + }); + + afterEach(() => { + // @ts-ignore + fetchMock.mockReset(); + }); + + it('can publish entries and retreive the next document view id', async () => { + const session = new Session('http://localhost:2020/graphql').setKeyPair( + new KeyPair(fixtures.privateKey), + ); + + const viewId = await session.publish( + fixtures.entries[3].encodedEntry, + fixtures.entries[3].encodedOperation, + ); + + expect(viewId).toEqual(fixtures.entries[3].entryHash); + }); + + it('throws when publishing without all required parameters', async () => { + const session = new Session('http://localhost:2020/graphql').setKeyPair( + new KeyPair(fixtures.privateKey), + ); + + await expect( + // @ts-ignore: We deliberately use the API wrong here + session.publish(null, fixtures.entries[3].encodedOperation), + ).rejects.toThrow(); + await expect( + // @ts-ignore: We deliberately use the API wrong here + session.publish(fixtures.entries[3].encodedEntry, null), + ).rejects.toThrow(); + }); +}); + +describe('create', () => { + let session: Session; + + beforeEach(() => { + fetchMock + .mock( + { + name: 'nextArgs', + url: 'http://localhost:2020/graphql', + body: { query: GQL_NEXT_ARGS }, + }, + { + data: { + nextArgs: fixtures.nextArgs[0], + }, + }, + ) + .mock( + { + name: 'publish', + url: 'http://localhost:2020/graphql', + body: { query: GQL_PUBLISH }, + }, + { + data: { + nextArgs: fixtures.nextArgs[1], + }, + }, + ); + }); + + afterEach(() => { + // @ts-ignore + fetchMock.mockReset(); + }); + + beforeEach(async () => { + session = new Session('http://localhost:2020/graphql'); + session.setKeyPair(new KeyPair(fixtures.privateKey)); + }); + + it('returns the id of the created document', async () => { + const fields = fixtures.operations[0].fields as Fields; + + await expect( + session.create(fields, { + schemaId: fixtures.schemaId, + }), + ).resolves.toBe(fixtures.entries[0].entryHash); + }); + + it('throws when missing a required parameter', async () => { + await expect( + // @ts-ignore: We deliberately use the API wrong here + session.setKeyPair(new KeyPair()).create(), + ).rejects.toThrow(); + }); +}); + +describe('update', () => { + let session: Session; + + beforeEach(() => { + fetchMock + .mock( + { + name: 'nextArgs', + url: 'http://localhost:2020/graphql', + body: { query: GQL_NEXT_ARGS }, + }, + { + data: { + nextArgs: fixtures.nextArgs[1], + }, + }, + ) + .mock( + { + name: 'publish', + url: 'http://localhost:2020/graphql', + body: { query: GQL_PUBLISH }, + }, + { + data: { + nextArgs: fixtures.nextArgs[2], + }, + }, + ); + }); + + afterEach(() => { + // @ts-ignore + fetchMock.mockReset(); + }); + + beforeEach(async () => { + session = new Session('http://localhost:2020/graphql'); + session.setKeyPair(new KeyPair(fixtures.privateKey)); + }); + + it('returns the local view id of the updated document', async () => { + const fields = fixtures.operations[1].fields as Fields; + const previous = fixtures.operations[1].previous as string[]; + + await expect( + session.update(fields, previous, { + schemaId: fixtures.schemaId, + }), + ).resolves.toBe(fixtures.entries[1].entryHash); + }); + + it('throws when missing a required parameter', async () => { + await expect( + // @ts-ignore: We deliberately use the API wrong here + session.update(null, { schemaId: fixtures.schemaId }), + ).rejects.toThrow(); + + await expect( + // @ts-ignore: We deliberately use the API wrong here + session.update({ + message: 'Doing it wrong', + }), + ).rejects.toThrow(); + }); +}); + +describe('delete', () => { + let session: Session; + + beforeEach(() => { + fetchMock + .mock( + { + name: 'nextArgs', + url: 'http://localhost:2020/graphql', + body: { query: GQL_NEXT_ARGS }, + }, + { + data: { + nextArgs: fixtures.nextArgs[3], + }, + }, + ) + .mock( + { + name: 'publish', + url: 'http://localhost:2020/graphql', + body: { query: GQL_PUBLISH }, + }, + { + data: { + nextArgs: fixtures.nextArgs[4], + }, + }, + ); + }); + + afterEach(() => { + // @ts-ignore + fetchMock.mockReset(); + }); + + beforeEach(async () => { + session = new Session('http://localhost:2020/graphql'); + session.setKeyPair(new KeyPair(fixtures.privateKey)); + }); + + it('returns the local view id of the deleted document', async () => { + const previous = fixtures.operations[3].previous as string[]; + + await expect( + session.delete(previous, { + schemaId: fixtures.schemaId, + }), + ).resolves.toBe(fixtures.entries[3].entryHash); + + expect(await session.setSchemaId(fixtures.schemaId).delete(previous)) + .resolves; + }); + + it('throws when missing a required parameter', async () => { + await expect( + // @ts-ignore: We deliberately use the API wrong here + session.delete(null, { schemaId: fixtures.schemaId }), + ).rejects.toThrow(); + + await expect( + // @ts-ignore: We deliberately use the API wrong here + session.delete(null), + ).rejects.toThrow(); + }); +}); diff --git a/test/test-data.json b/test/test-data.json deleted file mode 100644 index c6af28e..0000000 --- a/test/test-data.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "panda": { - "publicKey": "bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb03", - "privateKey": "738e6b967d03daf61da456061c7c80e7d75820da5ef2e690eff4fa46d6ab5d09", - "logs": [ - { - "encodedEntries": [ - { - "author": "bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb03", - "entryBytes": "00bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb0301016f0020bf7346f6aa2a2bc2e7616165cf14b79dc1063e96ad649e0bf6f32631b09143f724d65b0dc682733225236f3712d60f285966bfef2b6915d61b28baa6e8d42f0b8c27f94d300df41398206fcb2c9c93ca85b9d1a0b419c01ee7bf026c8fbee90c", - "entryHash": "00201c221b573b1e0c67c5e2c624a93419774cdf46b3d62414c44a698df1237b1c16", - "payloadBytes": "840100784A76656E75655F3030323063363535363761653337656665613239336533346139633764313366386632626632336462646333623563376239616234363239333131316334386663373862A1676D657373616765764F68682C206D79206669727374206D65737361676521", - "payloadHash": "00204b771d59d76e820cbae493682003e99b795e4e7c86a8d6b4c9ad836dc4c9bf1d", - "logId": "1", - "seqNum": "1" - }, - { - "author": "bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb03", - "entryBytes": "00bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb03010200201c221b573b1e0c67c5e2c624a93419774cdf46b3d62414c44a698df1237b1c16b30020d676301cf838abeab15ee5a40c053f0d644d5ee61290ff6b9c891fd98d6d1c8a0f3c2af785a95bcbe072b8ed21bdd00c9d20adab8653e1ba2020be9086d03f35179181a76844e3e201c2cc9a4f63b09fa99f00e086d7026c70b8d8b6c34ff001", - "entryHash": "0020b7188ef505c499bf6d2d4a121e0535285fd444105b3d0b141429880bbb6cf31b", - "payloadBytes": "850101784A76656E75655F30303230633635353637616533376566656132393365333461396337643133663866326266323364626463336235633762396162343632393331313163343866633738628178443030323031633232316235373362316530633637633565326336323461393334313937373463646634366233643632343134633434613639386466313233376231633136A1676D6573736167657357686963682049206E6F77207570646174652E", - "payloadHash": "0020f96e290e8f7ed747aefe0074b2f7aa678d4c7aff6877ad9344832a94132c55af", - "logId": "1", - "seqNum": "2" - }, - { - "author": "bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb03", - "entryBytes": "00bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb0301030020b7188ef505c499bf6d2d4a121e0535285fd444105b3d0b141429880bbb6cf31bf8fd00201c1ab5953daf80ad6636a246dba4de8424209755043acd7d85b01f930fd279fd9d9e38b66142d0a5e6c9bb0284044c92bdd00f0a98bce23d64a121115d1acee0714546a52781450fbede4503839b806e4fe99d2ccbc7985dac17dad25bc7d40e", - "entryHash": "0020a93a4c8b92b4c4e15bd38703a806015bc9f1e72d93e577a29ed73b09bcf9a2b5", - "payloadBytes": "850101784A76656E75655F30303230633635353637616533376566656132393365333461396337643133663866326266323364626463336235633762396162343632393331313163343866633738628178443030323062373138386566353035633439396266366432643461313231653035333532383566643434343130356233643062313431343239383830626262366366333162A1676D65737361676576416E64207468656E2075706461746520616761696E2E", - "payloadHash": "00201c1ab5953daf80ad6636a246dba4de8424209755043acd7d85b01f930fd279fd", - "logId": "1", - "seqNum": "3" - }, - { - "author": "bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb03", - "entryBytes": "00bedabb435758855968b3e2de2aa1f653adfbb392fcf9cb2295a68b2eca3cfb03010400201c221b573b1e0c67c5e2c624a93419774cdf46b3d62414c44a698df1237b1c160020a93a4c8b92b4c4e15bd38703a806015bc9f1e72d93e577a29ed73b09bcf9a2b59600204dcae01376ebdfd544a36b5146b5c95f0b1b6aa6ae6aa737fe29b7ab96dd57156a32d359a2e84b47d86fd2d33b6f9f466c28586bcd738b09901271fe710648e1cba6a146e6287e1edcc906424d33bd8aa3e2caaafe363af920717d01e6fdb706", - "entryHash": "0020172f7b7785956aa5a610d5cbe7b1a80a28e32a1d86ad24cfd82ccbd9c3f5c178", - "payloadBytes": "840102784A76656E75655F30303230633635353637616533376566656132393365333461396337643133663866326266323364626463336235633762396162343632393331313163343866633738628178443030323061393361346338623932623463346531356264333837303361383036303135626339663165373264393365353737613239656437336230396263663961326235", - "payloadHash": "0020bc70f67db1bfb2be8bbcf9f870884e247a519ff3fce02c7a60aef90cadce7d65", - "logId": "1", - "seqNum": "4" - } - ], - "decodedOperations": [ - { - "action": "create", - "schema": "venue_0020c65567ae37efea293e34a9c7d13f8f2bf23dbdc3b5c7b9ab46293111c48fc78b", - "version": 1, - "fields": { - "message": "Ohh, my first message!" - } - }, - { - "action": "update", - "schema": "venue_0020c65567ae37efea293e34a9c7d13f8f2bf23dbdc3b5c7b9ab46293111c48fc78b", - "version": 1, - "previous": [ - "00201c221b573b1e0c67c5e2c624a93419774cdf46b3d62414c44a698df1237b1c16" - ], - "fields": { - "message": "Which I now update." - } - }, - { - "action": "update", - "schema": "venue_0020c65567ae37efea293e34a9c7d13f8f2bf23dbdc3b5c7b9ab46293111c48fc78b", - "version": 1, - "previous": [ - "0020b7188ef505c499bf6d2d4a121e0535285fd444105b3d0b141429880bbb6cf31b" - ], - "fields": { - "message": "And then update again." - } - }, - { - "action": "delete", - "schema": "venue_0020c65567ae37efea293e34a9c7d13f8f2bf23dbdc3b5c7b9ab46293111c48fc78b", - "version": 1, - "previous": [ - "0020a93a4c8b92b4c4e15bd38703a806015bc9f1e72d93e577a29ed73b09bcf9a2b5" - ] - } - ], - "nextArgs": [ - { - "backlink": null, - "skiplink": null, - "seqNum": "1", - "logId": "1" - }, - { - "backlink": "00201c221b573b1e0c67c5e2c624a93419774cdf46b3d62414c44a698df1237b1c16", - "skiplink": null, - "seqNum": "2", - "logId": "1" - }, - { - "backlink": "0020b7188ef505c499bf6d2d4a121e0535285fd444105b3d0b141429880bbb6cf31b", - "skiplink": null, - "seqNum": "3", - "logId": "1" - }, - { - "backlink": "0020a93a4c8b92b4c4e15bd38703a806015bc9f1e72d93e577a29ed73b09bcf9a2b5", - "skiplink": "00201c221b573b1e0c67c5e2c624a93419774cdf46b3d62414c44a698df1237b1c16", - "seqNum": "4", - "logId": "1" - }, - { - "backlink": "0020172f7b7785956aa5a610d5cbe7b1a80a28e32a1d86ad24cfd82ccbd9c3f5c178", - "skiplink": null, - "seqNum": "5", - "logId": "1" - } - ] - } - ] - } -} diff --git a/tsconfig.json b/tsconfig.json index 35ab66a..c29ff34 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,7 @@ "lib": ["dom"], "resolveJsonModule": true, "sourceMap": true, + "inlineSources": true, "types": ["jest", "node"] } }