diff --git a/apps/ans/frontend/package.json b/apps/ans/frontend/package.json index 10efad60a2..a163e00508 100644 --- a/apps/ans/frontend/package.json +++ b/apps/ans/frontend/package.json @@ -17,18 +17,23 @@ "@daml/types": "^3.4.11", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", + "@lfdecentralizedtrust/openapi-ts-client": "file:../openapi-ts-client/dist", "@mui/icons-material": "^7.3.4", "@mui/material": "^7.3.4", "@tanstack/react-query": "5.90.20", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "msw": "^2.14.2", "oidc-client-ts": "2.2.1", - "@lfdecentralizedtrust/openapi-ts-client": "file:../openapi-ts-client/dist", "react": "18.3.1", "react-dom": "18.3.1", "react-helmet-async": "^2.0.5", "react-oidc-context": "2.2.2", "use-debounce": "^9.0.4", - "uuid": "9.0.0", - "web-vitals": "4.2.4" + "uuid": "^14.0.0", + "web-vitals": "4.2.4", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -46,7 +51,7 @@ "@types/react-dom": "18.3.6", "@types/uuid": "8.3.4", "@vitejs/plugin-react": "^6.0.1", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", diff --git a/apps/ans/frontend/src/__tests__/setup/setup.ts b/apps/ans/frontend/src/__tests__/setup/setup.ts index 68f820501c..e53a2de909 100644 --- a/apps/ans/frontend/src/__tests__/setup/setup.ts +++ b/apps/ans/frontend/src/__tests__/setup/setup.ts @@ -1,5 +1,16 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 + +// happy-dom@20 doesn't lowercase header names during iteration as the Fetch +// spec requires; the openapi clients read `headers["content-type"]`, so without +// this patch they fail to parse JSON responses from MSW. +const _origForEach = Headers.prototype.forEach; +Headers.prototype.forEach = function (cb, thisArg) { + return _origForEach.call(this, function (value: string, name: string, parent: Headers) { + cb.call(thisArg, value, name.toLowerCase(), parent); + }); +}; + import crypto from 'crypto'; import { vi } from 'vitest'; diff --git a/apps/common/frontend-test-handlers/package.json b/apps/common/frontend-test-handlers/package.json index c17e399da6..1f368b2b1a 100644 --- a/apps/common/frontend-test-handlers/package.json +++ b/apps/common/frontend-test-handlers/package.json @@ -10,9 +10,9 @@ "@daml/types": "^3.4.11", "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/node": "22.14.0", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-config-prettier": "10.1.1", - "msw": "^1.2.5", + "msw": "^2.14.2", "nodemon": "^3.1.9", "prettier": "3.5.3", "typescript": "5.8.3", @@ -27,5 +27,12 @@ "lint:check": "eslint --ignore-pattern src/com/* --max-warnings=0 -- src", "lint:fix": "eslint --ignore-pattern src/com/* --fix --max-warnings=0 -- src", "start": "tsc --watch" + }, + "dependencies": { + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "uuid": "^14.0.0", + "zod": "^3.25.76" } } diff --git a/apps/common/frontend-test-handlers/src/mocks/handlers/dso-info-handler.ts b/apps/common/frontend-test-handlers/src/mocks/handlers/dso-info-handler.ts index ecceb85c9b..7ae4865302 100644 --- a/apps/common/frontend-test-handlers/src/mocks/handlers/dso-info-handler.ts +++ b/apps/common/frontend-test-handlers/src/mocks/handlers/dso-info-handler.ts @@ -1,4 +1,4 @@ -import { rest, RestHandler } from 'msw'; +import { http, HttpHandler, HttpResponse } from 'msw'; import { getAmuletRulesConfig } from '../helpers/amulet-config-helper'; import { getDsoRulesConfig } from '../helpers/dso-config-helper'; @@ -592,8 +592,8 @@ export const dsoInfo = { ], }; -export function dsoInfoHandler(baseUrl: string): RestHandler { - return rest.get(`${baseUrl}/v0/dso`, (_, res, ctx) => { - return res(ctx.json(dsoInfo)); +export function dsoInfoHandler(baseUrl: string): HttpHandler { + return http.get(`${baseUrl}/v0/dso`, () => { + return HttpResponse.json(dsoInfo); }); } diff --git a/apps/common/frontend-test-handlers/src/mocks/handlers/validator-licenses-handler.ts b/apps/common/frontend-test-handlers/src/mocks/handlers/validator-licenses-handler.ts index 37375fd1c3..c8beb39c44 100644 --- a/apps/common/frontend-test-handlers/src/mocks/handlers/validator-licenses-handler.ts +++ b/apps/common/frontend-test-handlers/src/mocks/handlers/validator-licenses-handler.ts @@ -1,11 +1,11 @@ -import { rest, RestHandler } from 'msw'; +import { http, HttpHandler, HttpResponse } from 'msw'; import { ValidatorLicense } from '@daml.js/splice-amulet/lib/Splice/ValidatorLicense'; -export function validatorLicensesHandler(baseUrl: string): RestHandler { - return rest.get(`${baseUrl}/v0/admin/validator/licenses`, (req, res, ctx) => { - const n = parseInt(req.url.searchParams.get('limit')!); - const after = req.url.searchParams.get('after'); +export function validatorLicensesHandler(baseUrl: string): HttpHandler { + return http.get(`${baseUrl}/v0/admin/validator/licenses`, ({ request }) => { + const n = parseInt(new URL(request.url).searchParams.get('limit')!); + const after = new URL(request.url).searchParams.get('after'); const from = after ? parseInt(after) + 1 : 0; const aTimestamp = '2024-09-26T16:15:36Z'; const validatorLicenses = Array.from({ length: n }, (_, i) => { @@ -30,11 +30,9 @@ export function validatorLicensesHandler(baseUrl: string): RestHandler { template_id: ValidatorLicense.templateId, }; }); - return res( - ctx.json({ - validator_licenses: validatorLicenses, - next_page_token: from + n, - }) - ); + return HttpResponse.json({ + validator_licenses: validatorLicenses, + next_page_token: from + n, + }); }); } diff --git a/apps/common/frontend-test-handlers/src/mocks/helpers/amulet-config-helper.ts b/apps/common/frontend-test-handlers/src/mocks/helpers/amulet-config-helper.ts index ac94e2256b..452cf07c6f 100644 --- a/apps/common/frontend-test-handlers/src/mocks/helpers/amulet-config-helper.ts +++ b/apps/common/frontend-test-handlers/src/mocks/helpers/amulet-config-helper.ts @@ -253,62 +253,65 @@ export function getExpectedAmuletRulesConfigDiffsHTML( replacementCreateFee: string ): string { const mock = ` -
+}
  • transferPreapprovalFee
    null
  • featuredAppActivityMarkerAmount
    null
  • optDevelopmentFundManager
    null
  • externalPartyConfigStateTickDuration
    null
  • `; return mock; } diff --git a/apps/common/frontend-test-handlers/src/mocks/helpers/dso-config-helper.ts b/apps/common/frontend-test-handlers/src/mocks/helpers/dso-config-helper.ts index 28e031cb37..66d5140aff 100644 --- a/apps/common/frontend-test-handlers/src/mocks/helpers/dso-config-helper.ts +++ b/apps/common/frontend-test-handlers/src/mocks/helpers/dso-config-helper.ts @@ -130,99 +130,42 @@ export function getExpectedDsoRulesConfigDiffsHTML(
    +}
  • nextScheduledLogicalSynchronizerUpgrade
    null
  • `; const voteResultDiff = `
    +}
  • nextScheduledLogicalSynchronizerUpgrade
    null
  • `; return isVoteResult ? voteResultDiff : voteRequestDiff; diff --git a/apps/common/frontend-test-utils/package.json b/apps/common/frontend-test-utils/package.json index 6676672b24..619e70005f 100644 --- a/apps/common/frontend-test-utils/package.json +++ b/apps/common/frontend-test-utils/package.json @@ -9,7 +9,7 @@ "devDependencies": { "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/node": "22.14.0", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-config-prettier": "10.1.1", "nodemon": "^3.1.9", "prettier": "3.5.3", @@ -25,5 +25,13 @@ "lint:check": "eslint --ignore-pattern src/com/* --max-warnings=0 -- src", "lint:fix": "eslint --ignore-pattern src/com/* --fix --max-warnings=0 -- src", "start": "tsc --watch" + }, + "dependencies": { + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "msw": "^2.14.2", + "uuid": "^14.0.0", + "zod": "^3.25.76" } } diff --git a/apps/common/frontend-test-vite-utils/package.json b/apps/common/frontend-test-vite-utils/package.json index 6dfeb836d7..8b4b80a8a6 100644 --- a/apps/common/frontend-test-vite-utils/package.json +++ b/apps/common/frontend-test-vite-utils/package.json @@ -14,9 +14,9 @@ "devDependencies": { "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/node": "22.14.0", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-config-prettier": "10.1.1", - "msw": "^1.2.5", + "msw": "^2.14.2", "nodemon": "^3.1.9", "prettier": "3.5.3", "typescript": "5.8.3", @@ -32,5 +32,12 @@ "lint:check": "eslint --ignore-pattern src/com/* --max-warnings=0 -- src", "lint:fix": "eslint --ignore-pattern src/com/* --fix --max-warnings=0 -- src", "start": "nodemon -V -e ts,json -i lib/ -x \"npm run build\"" + }, + "dependencies": { + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "uuid": "^14.0.0", + "zod": "^3.25.76" } } diff --git a/apps/common/frontend/package.json b/apps/common/frontend/package.json index 3e073a75ac..b716fe8a02 100644 --- a/apps/common/frontend/package.json +++ b/apps/common/frontend/package.json @@ -17,23 +17,26 @@ "@daml/types": "^3.4.11", "@js-temporal/polyfill": "^0.4.4", "@lfdecentralizedtrust/splice-common-frontend-utils": "0.1.0", + "@dmsnell/diff-match-patch": "^1.1.0", "@lfdecentralizedtrust/splice-common-typeface-termina": "1.0.0", "@lfdecentralizedtrust/splitwell-openapi": "0.0.1", "@lfdecentralizedtrust/sv-openapi": "0.0.1", "@tanstack/react-query": "5.90.20", "date-fns": "2.29.3", "decimal.js-light": "2.5.1", - "dompurify": "3.2.4", + "dompurify": "^3.4.2", "grpc-web": "1.3.1", "html-react-parser": "5.1.15", - "jose": "4.10.3", - "jsondiffpatch": "0.6.0", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "msw": "^2.14.2", "react-intersection-observer": "^9.15.1", "react-oidc-context": "2.2.2", "react-router": "^7.12.0", + "uuid": "^14.0.0", "web-vitals": "4.2.4", "xunit-viewer": "^10.6.1", - "zod": "3.19.1" + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -47,14 +50,14 @@ "@types/react": "18.3.12", "@types/react-dom": "18.3.6", "@types/semver": "^7.7.0", - "eslint": "9.24.0", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^9.39.4", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", "prettier": "3.5.3", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", - "@vitejs/plugin-react": "^6.0.1", "vite": "^8.0.7", "vite-tsconfig-paths": "^6.1.1", "vitest": "^3.1.1" diff --git a/apps/common/frontend/src/__tests__/setup/setup.ts b/apps/common/frontend/src/__tests__/setup/setup.ts index bb0b167fb7..5d304d03ea 100644 --- a/apps/common/frontend/src/__tests__/setup/setup.ts +++ b/apps/common/frontend/src/__tests__/setup/setup.ts @@ -1,5 +1,16 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 + +// happy-dom@20 doesn't lowercase header names during iteration as the Fetch +// spec requires; the openapi clients read `headers["content-type"]`, so without +// this patch they fail to parse JSON responses from MSW. +const _origForEach = Headers.prototype.forEach; +Headers.prototype.forEach = function (cb, thisArg) { + return _origForEach.call(this, function (value: string, name: string, parent: Headers) { + cb.call(thisArg, value, name.toLowerCase(), parent); + }); +}; + import { cleanup } from '@testing-library/react'; import { beforeEach, afterEach } from 'vitest'; diff --git a/apps/common/frontend/src/components/PrettyJsonDiff.tsx b/apps/common/frontend/src/components/PrettyJsonDiff.tsx index 82a3cc0a5d..8120708459 100644 --- a/apps/common/frontend/src/components/PrettyJsonDiff.tsx +++ b/apps/common/frontend/src/components/PrettyJsonDiff.tsx @@ -1,8 +1,8 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 +import { diff_match_patch as DiffMatchPatch } from '@dmsnell/diff-match-patch'; import * as jsondiffpatch from 'jsondiffpatch'; import * as htmlFormatter from 'jsondiffpatch/formatters/html'; -import DiffMatchPatch from 'diff-match-patch'; import DOMPurify from 'dompurify'; import parse from 'html-react-parser'; import React from 'react'; @@ -26,7 +26,7 @@ const jsondiffpatchInstance = jsondiffpatch.create({ }); const JsonDiffStyles = () => ( - // original template: https://esm.sh/jsondiffpatch@0.6.0/lib/formatters/styles/html.css + // original template: https://esm.sh/jsondiffpatch@0.7.3/lib/formatters/styles/html.css =8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "common/frontend-test-handlers/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "common/frontend-test-handlers/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "common/frontend-test-handlers/node_modules/msw": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/msw/-/msw-1.3.5.tgz", - "integrity": "sha512-nG3fpmBXxFbKSIdk6miPuL3KjU6WMxgoW4tG1YgnP1M+TRG3Qn7b7R0euKAHq4vpwARHb18ZyfZljSxsTnMX2w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mswjs/cookies": "^0.2.2", - "@mswjs/interceptors": "^0.17.10", - "@open-draft/until": "^1.0.3", - "@types/cookie": "^0.4.1", - "@types/js-levenshtein": "^1.1.1", - "chalk": "^4.1.1", - "chokidar": "^3.4.2", - "cookie": "^0.4.2", - "graphql": "^16.8.1", - "headers-polyfill": "3.2.5", - "inquirer": "^8.2.0", - "is-node-process": "^1.2.0", - "js-levenshtein": "^1.1.6", - "node-fetch": "^2.6.7", - "outvariant": "^1.4.0", - "path-to-regexp": "^6.3.0", - "strict-event-emitter": "^0.4.3", - "type-fest": "^2.19.0", - "yargs": "^17.3.1" - }, - "bin": { - "msw": "cli/index.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mswjs" - }, - "peerDependencies": { - "typescript": ">= 4.4.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "common/frontend-test-handlers/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "dev": true, - "license": "MIT" - }, "common/frontend-test-utils": { "name": "@lfdecentralizedtrust/splice-common-test-utils", "version": "0.1.0", + "dependencies": { + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "msw": "^2.14.2", + "uuid": "^14.0.0", + "zod": "^3.25.76" + }, "devDependencies": { "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/node": "22.14.0", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-config-prettier": "10.1.1", "nodemon": "^3.1.9", "prettier": "3.5.3", @@ -403,115 +337,25 @@ "common/frontend-test-vite-utils": { "name": "@lfdecentralizedtrust/splice-common-test-vite-utils", "version": "0.1.0", + "dependencies": { + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "uuid": "^14.0.0", + "zod": "^3.25.76" + }, "devDependencies": { "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/node": "22.14.0", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-config-prettier": "10.1.1", - "msw": "^1.2.5", + "msw": "^2.14.2", "nodemon": "^3.1.9", "prettier": "3.5.3", "typescript": "5.8.3", "typescript-eslint": "^8.30.1" } }, - "common/frontend-test-vite-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "common/frontend-test-vite-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "common/frontend-test-vite-utils/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "common/frontend-test-vite-utils/node_modules/msw": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/msw/-/msw-1.3.5.tgz", - "integrity": "sha512-nG3fpmBXxFbKSIdk6miPuL3KjU6WMxgoW4tG1YgnP1M+TRG3Qn7b7R0euKAHq4vpwARHb18ZyfZljSxsTnMX2w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mswjs/cookies": "^0.2.2", - "@mswjs/interceptors": "^0.17.10", - "@open-draft/until": "^1.0.3", - "@types/cookie": "^0.4.1", - "@types/js-levenshtein": "^1.1.1", - "chalk": "^4.1.1", - "chokidar": "^3.4.2", - "cookie": "^0.4.2", - "graphql": "^16.8.1", - "headers-polyfill": "3.2.5", - "inquirer": "^8.2.0", - "is-node-process": "^1.2.0", - "js-levenshtein": "^1.1.6", - "node-fetch": "^2.6.7", - "outvariant": "^1.4.0", - "path-to-regexp": "^6.3.0", - "strict-event-emitter": "^0.4.3", - "type-fest": "^2.19.0", - "yargs": "^17.3.1" - }, - "bin": { - "msw": "cli/index.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mswjs" - }, - "peerDependencies": { - "typescript": ">= 4.4.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "common/frontend-test-vite-utils/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "dev": true, - "license": "MIT" - }, "common/frontend-typeface-lato": { "name": "@lfdecentralizedtrust/splice-common-typeface-lato", "version": "1.0.0", @@ -1758,8 +1602,13 @@ "version": "0.1.0", "dependencies": { "@js-temporal/polyfill": "^0.4.4", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "msw": "^2.14.2", + "uuid": "^14.0.0", "web-vitals": "4.2.4", - "zod": "3.19.1" + "zod": "^3.25.76" }, "devDependencies": { "@tanstack/eslint-plugin-query": "5.91.3", @@ -1767,7 +1616,7 @@ "@types/node": "22.14.0", "@types/react": "18.3.12", "@types/react-dom": "18.3.6", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-config-prettier": "10.1.1", "prettier": "3.5.3", "typescript": "5.8.3", @@ -1873,9 +1722,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1933,9 +1782,9 @@ "license": "MIT" }, "node_modules/@codemirror/autocomplete": { - "version": "6.18.6", - "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz", - "integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==", + "version": "6.20.1", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.1.tgz", + "integrity": "sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -1945,35 +1794,35 @@ } }, "node_modules/@codemirror/commands": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", - "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.3.tgz", + "integrity": "sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.4.0", + "@codemirror/state": "^6.6.0", "@codemirror/view": "^6.27.0", "@lezer/common": "^1.1.0" } }, "node_modules/@codemirror/language": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz", - "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==", + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.3.tgz", + "integrity": "sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", - "@lezer/common": "^1.1.0", + "@lezer/common": "^1.5.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0", "style-mod": "^4.0.0" } }, "node_modules/@codemirror/lint": { - "version": "6.8.5", - "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz", - "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==", + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.5.tgz", + "integrity": "sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", @@ -1982,29 +1831,29 @@ } }, "node_modules/@codemirror/search": { - "version": "6.5.10", - "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz", - "integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.7.0.tgz", + "integrity": "sha512-ZvGm99wc/s2cITtMT15LFdn8aH/aS+V+DqyGq/N5ZlV5vWtH+nILvC2nw0zX7ByNoHHDZ2IxxdW38O0tc5nVHg==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", + "@codemirror/view": "^6.37.0", "crelt": "^1.0.5" } }, "node_modules/@codemirror/state": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", - "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.6.0.tgz", + "integrity": "sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==", "license": "MIT", "dependencies": { "@marijn/find-cluster-break": "^1.0.0" } }, "node_modules/@codemirror/theme-one-dark": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", - "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.3.tgz", + "integrity": "sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -2014,12 +1863,13 @@ } }, "node_modules/@codemirror/view": { - "version": "6.36.6", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.6.tgz", - "integrity": "sha512-uxugGLet+Nzp0Jcit8Hn3LypM8ioMLKTsdf8FRoT3HWvZtb9GhaWMe0Cc15rz90Ljab4YFJiAulmIVB74OY0IQ==", + "version": "6.41.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.41.1.tgz", + "integrity": "sha512-ToDnWKbBnke+ZLrP6vgTTDScGi5H37YYuZGniQaBzxMVdtCxMrslsmtnOvbPZk4RX9bvkQqnWR/WS/35tJA0qg==", "license": "MIT", "dependencies": { - "@codemirror/state": "^6.5.0", + "@codemirror/state": "^6.6.0", + "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } @@ -2131,6 +1981,12 @@ "lodash": "^4.5" } }, + "node_modules/@dmsnell/diff-match-patch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@dmsnell/diff-match-patch/-/diff-match-patch-1.1.0.tgz", + "integrity": "sha512-yejLPmM5pjsGvxS9gXablUSbInW7H976c/FJ4iQxWIm7/38xBySRemTPDe34lhg1gVLbJntX0+sH0jYfU+PN9A==", + "license": "Apache-2.0" + }, "node_modules/@emnapi/core": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", @@ -2706,7 +2562,6 @@ "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dev": true, "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -2725,22 +2580,20 @@ "version": "4.12.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "dev": true, + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.6", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2750,7 +2603,6 @@ "version": "1.1.14", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2761,7 +2613,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -2771,20 +2622,21 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", - "dev": true, + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", - "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", - "dev": true, + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" @@ -2794,20 +2646,19 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -2821,7 +2672,6 @@ "version": "1.1.14", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2832,7 +2682,6 @@ "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -2845,7 +2694,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -2855,57 +2703,43 @@ } }, "node_modules/@eslint/js": { - "version": "9.25.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.1.tgz", - "integrity": "sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==", - "dev": true, + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "dev": true, + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "dev": true, + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.13.0", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18.0" @@ -2915,7 +2749,6 @@ "version": "0.16.6", "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.1", @@ -2929,7 +2762,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -2943,7 +2775,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.22" @@ -2957,7 +2788,6 @@ "version": "0.4.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -2967,18 +2797,26 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@inquirer/external-editor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", - "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", - "dev": true, + "node_modules/@inquirer/ansi": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.5.tgz", + "integrity": "sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==", + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/confirm": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.0.12.tgz", + "integrity": "sha512-h9FgGun3QwVYNj5TWIZZ+slii73bMoBFjPfVIGtnFuL4t8gBiNDV9PcSfIzkuxvgquJKt9nr1QzszpBzTbH8Og==", "license": "MIT", "dependencies": { - "chardet": "^2.1.1", - "iconv-lite": "^0.7.0" + "@inquirer/core": "^11.1.9", + "@inquirer/type": "^4.0.5" }, "engines": { - "node": ">=18" + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" }, "peerDependencies": { "@types/node": ">=18" @@ -2989,21 +2827,56 @@ } } }, - "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "dev": true, + "node_modules/@inquirer/core": { + "version": "11.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.1.9.tgz", + "integrity": "sha512-BDE4fG22uYh1bGSifcj7JSx119TVYNViMhMu85usp4Fswrzh6M0DV3yld64jA98uOAa2GSQ4Bg4bZRm2d2cwSg==", "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "@inquirer/ansi": "^2.0.5", + "@inquirer/figures": "^2.0.5", + "@inquirer/type": "^4.0.5", + "cli-width": "^4.1.0", + "fast-wrap-ansi": "^0.2.0", + "mute-stream": "^3.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.5.tgz", + "integrity": "sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==", + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/type": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.5.tgz", + "integrity": "sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==", + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@jest/expect-utils": { @@ -3132,24 +3005,24 @@ } }, "node_modules/@lezer/common": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", - "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz", + "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==", "license": "MIT" }, "node_modules/@lezer/highlight": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", - "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.3.tgz", + "integrity": "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==", "license": "MIT", "dependencies": { - "@lezer/common": "^1.0.0" + "@lezer/common": "^1.3.0" } }, "node_modules/@lezer/lr": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", - "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz", + "integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==", "license": "MIT", "dependencies": { "@lezer/common": "^1.0.0" @@ -3257,49 +3130,28 @@ "node": ">=6.0.0" } }, - "node_modules/@mswjs/cookies": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-0.2.2.tgz", - "integrity": "sha512-mlN83YSrcFgk7Dm1Mys40DLssI1KdJji2CMKN8eOlBqsTADYzj2+jWzsANsUTFbxDMWPD5e9bfA1RGqBpS3O1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/set-cookie-parser": "^2.4.0", - "set-cookie-parser": "^2.4.6" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@mswjs/interceptors": { - "version": "0.17.10", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.17.10.tgz", - "integrity": "sha512-N8x7eSLGcmUFNWZRxT1vsHvypzIRgQYdG0rJey/rZCy6zT/30qDt8Joj7FxzGNLSwXbeZqJOMqDurp7ra4hgbw==", - "dev": true, + "version": "0.41.8", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.41.8.tgz", + "integrity": "sha512-pRLMNKTSGRoLq+KnEB/7OY5vijw1XmcheAAOiv6pj7W1FG32kAGqj1C/RK/cqxRGr1Fh+zBi8sDur8kj3EQv6A==", "license": "MIT", "dependencies": { - "@open-draft/until": "^1.0.3", - "@types/debug": "^4.1.7", - "@xmldom/xmldom": "^0.8.3", - "debug": "^4.3.3", - "headers-polyfill": "3.2.5", - "outvariant": "^1.2.1", - "strict-event-emitter": "^0.2.4", - "web-encoding": "^1.1.5" + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, - "node_modules/@mswjs/interceptors/node_modules/strict-event-emitter": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.2.8.tgz", - "integrity": "sha512-KDf/ujU8Zud3YaLtMCcTI4xkZlZVIYxTLr+XIULexP+77EEVWixeXroLUXQXiVtH4XH2W7jr/3PT1v3zBuvc3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "events": "^3.3.0" - } + "node_modules/@mswjs/interceptors/node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "license": "MIT" }, "node_modules/@mui/core-downloads-tracker": { "version": "7.3.4", @@ -4075,16 +3927,31 @@ "node": ">= 8" } }, - "node_modules/@open-draft/until": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-1.0.3.tgz", - "integrity": "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==", - "dev": true, + "node_modules/@open-draft/deferred-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-3.0.0.tgz", + "integrity": "sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA==", "license": "MIT" }, - "node_modules/@oxc-project/types": { - "version": "0.123.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.123.0.tgz", + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "license": "MIT" + }, + "node_modules/@oxc-project/types": { + "version": "0.123.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.123.0.tgz", "integrity": "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew==", "dev": true, "license": "MIT", @@ -5234,38 +5101,15 @@ "license": "MIT", "peer": true }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", "license": "MIT", "dependencies": { "@types/node": "*" } }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/diff-match-patch": { - "version": "1.0.36", - "resolved": "https://registry.npmjs.org/@types/diff-match-patch/-/diff-match-patch-1.0.36.tgz", - "integrity": "sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==", - "license": "MIT" - }, "node_modules/@types/dompurify": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", @@ -5280,7 +5124,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, "node_modules/@types/google-protobuf": { @@ -5350,18 +5193,10 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/js-levenshtein": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@types/js-levenshtein/-/js-levenshtein-1.1.3.tgz", - "integrity": "sha512-jd+Q+sD20Qfu9e2aEXogiO3vpOC1PYJOUdyN9gvs4Qrvkg4wF43L5OhqrPeokdv8TL0/mXoYfpkcoGZMNN2pkQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, "license": "MIT" }, "node_modules/@types/json5": { @@ -5377,13 +5212,6 @@ "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", "license": "MIT" }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { "version": "22.14.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz", @@ -5445,7 +5273,6 @@ "version": "2.4.10", "resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.10.tgz", "integrity": "sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -5458,6 +5285,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/statuses": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.6.tgz", + "integrity": "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==", + "license": "MIT" + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -5490,7 +5323,6 @@ "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -5898,9 +5730,9 @@ } }, "node_modules/@uiw/codemirror-extensions-basic-setup": { - "version": "4.23.11", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.11.tgz", - "integrity": "sha512-U31s5LEqEKFU4SPz1tldfrPohKddxC02z1kTnWe50k+K0CYK+PtISD5ufH/PVC0EgGL+c0TydTx72nRMwaeC4A==", + "version": "4.25.9", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.25.9.tgz", + "integrity": "sha512-QFAqr+pu6lDmNpAlecODcF49TlsrZ0bj15zPzfhiqSDl+Um3EsDLFLppixC7kFLn+rdDM2LTvVjn5CPvefpRgw==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -5925,16 +5757,16 @@ } }, "node_modules/@uiw/react-codemirror": { - "version": "4.23.11", - "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.11.tgz", - "integrity": "sha512-oMUXl/yu/a8qKy7w7q769kH2TPlvPln6IpvkjXQX90ziD8GHRFLDz+Ij51D2RRwB3glrkPnhCN9YC+PDlnmhqA==", + "version": "4.25.9", + "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.25.9.tgz", + "integrity": "sha512-HftqCBUYShAOH0pGi1CHP8vfm5L8fQ3+0j0VI6lQD6QpK+UBu3J7nxfEN5O/BXMilMNf9ZyFJRvRcuMMOLHMng==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.6", "@codemirror/commands": "^6.1.0", "@codemirror/state": "^6.1.1", "@codemirror/theme-one-dark": "^6.0.0", - "@uiw/codemirror-extensions-basic-setup": "4.23.11", + "@uiw/codemirror-extensions-basic-setup": "4.25.9", "codemirror": "^6.0.0" }, "funding": { @@ -5946,8 +5778,8 @@ "@codemirror/theme-one-dark": ">=6.0.0", "@codemirror/view": ">=6.0.0", "codemirror": ">=6.0.0", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "react": ">=17.0.0", + "react-dom": ">=17.0.0" } }, "node_modules/@vitest/expect": { @@ -6085,24 +5917,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", - "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@zxing/text-encoding": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", - "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", - "dev": true, - "license": "(Unlicense OR Apache-2.0)", - "optional": true - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -6129,10 +5943,9 @@ } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "dev": true, + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -6145,7 +5958,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -6155,7 +5967,6 @@ "version": "6.15.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -6168,35 +5979,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -6236,7 +6018,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, "license": "Python-2.0" }, "node_modules/aria-query": { @@ -6495,7 +6276,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -6548,58 +6328,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/body-parser": { "version": "1.20.5", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", @@ -6823,9 +6551,9 @@ } }, "node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -6834,13 +6562,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chardet": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", - "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", - "dev": true, - "license": "MIT" - }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -6891,40 +6612,13 @@ "node": ">=8" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "license": "ISC", "engines": { - "node": ">= 10" + "node": ">= 12" } }, "node_modules/cliui": { @@ -6941,16 +6635,6 @@ "node": ">=12" } }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -6961,9 +6645,9 @@ } }, "node_modules/codemirror": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", - "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz", + "integrity": "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -6997,7 +6681,6 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, "license": "MIT" }, "node_modules/console-clear": { @@ -7037,9 +6720,9 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -7052,9 +6735,9 @@ "license": "MIT" }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -7062,6 +6745,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cosmiconfig": { @@ -7099,7 +6786,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -7252,22 +6938,8 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, "license": "MIT" }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -7352,12 +7024,6 @@ "node": ">=8" } }, - "node_modules/diff-match-patch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", - "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", - "license": "Apache-2.0" - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -7441,9 +7107,9 @@ } }, "node_modules/dompurify": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz", - "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.2.tgz", + "integrity": "sha512-lHeS9SA/IKeIFFyYciHBr2n0v1VMPlSj843HdLOwjb2OxNwdq9Xykxqhk+FE42MzAdHvInbAolSE4mhahPpjXA==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -7500,20 +7166,21 @@ } }, "node_modules/engine.io": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", - "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.7.tgz", + "integrity": "sha512-DgOngfDKM2EviOH3Mr9m7ks1q8roetLy/IMmYthAYzbpInMbYc/GS+fWFA3rl1gvwKVsQrVV61fo5emD1y3OJQ==", "license": "MIT", "dependencies": { "@types/cors": "^2.8.12", "@types/node": ">=10.0.0", + "@types/ws": "^8.5.12", "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.7.2", "cors": "~2.8.5", - "debug": "~4.3.1", + "debug": "~4.4.1", "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" + "ws": "~8.18.3" }, "engines": { "node": ">=10.2.0" @@ -7528,36 +7195,10 @@ "node": ">=10.0.0" } }, - "node_modules/engine.io/node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/engine.io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/engine.io/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -7901,33 +7542,31 @@ } }, "node_modules/eslint": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz", - "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==", - "dev": true, + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.0", - "@eslint/core": "^0.12.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.24.0", - "@eslint/plugin-kit": "^0.2.7", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -7939,7 +7578,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -8265,10 +7904,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "dev": true, + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -8285,7 +7923,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8294,21 +7931,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", - "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8324,7 +7950,6 @@ "version": "1.1.14", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -8335,7 +7960,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8349,10 +7973,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8365,7 +7988,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -8378,7 +8000,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -8388,15 +8009,14 @@ } }, "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "dev": true, + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.14.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8406,10 +8026,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8422,7 +8041,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -8435,7 +8053,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -8448,7 +8065,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -8468,7 +8084,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -8593,7 +8208,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-glob": { @@ -8617,16 +8231,38 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, "license": "MIT" }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz", + "integrity": "sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==", + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, "node_modules/fastq": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", @@ -8644,43 +8280,16 @@ "dev": true, "license": "MIT" }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "license": "MIT", "dependencies": { - "escape-string-regexp": "^1.0.5" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -8738,7 +8347,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -8755,7 +8363,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", @@ -8769,7 +8376,6 @@ "version": "3.4.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", - "dev": true, "license": "ISC" }, "node_modules/for-each": { @@ -8894,9 +8500,9 @@ } }, "node_modules/get-port": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", - "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.2.0.tgz", + "integrity": "sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==", "license": "MIT", "engines": { "node": ">=16" @@ -9015,7 +8621,6 @@ "version": "16.13.2", "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz", "integrity": "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==", - "dev": true, "license": "MIT", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" @@ -9105,7 +8710,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9181,10 +8785,19 @@ } }, "node_modules/headers-polyfill": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.2.5.tgz", - "integrity": "sha512-tUCGvt191vNSQgttSyJoibR+VO+I6+iCHIUdhzEMJKE+EAL8BwCN7fUOZlY4ofOelNHsK+gEjxB/B+9N3EWtdA==", - "dev": true, + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-5.0.1.tgz", + "integrity": "sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA==", + "license": "MIT", + "dependencies": { + "@types/set-cookie-parser": "^2.4.10", + "set-cookie-parser": "^3.0.1" + } + }, + "node_modules/headers-polyfill/node_modules/set-cookie-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz", + "integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==", "license": "MIT" }, "node_modules/hoist-non-react-statics": { @@ -9311,7 +8924,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -9344,7 +8956,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -9372,81 +8983,6 @@ "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==", "license": "MIT" }, - "node_modules/inquirer": { - "version": "8.2.7", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", - "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/external-editor": "^1.0.0", - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^6.0.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -9486,23 +9022,6 @@ "node": ">= 0.10" } }, - "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -9720,16 +9239,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -9747,7 +9256,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", - "dev": true, "license": "MIT" }, "node_modules/is-number": { @@ -9875,19 +9383,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-weakmap": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", @@ -9945,7 +9440,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/iterator.prototype": { @@ -10253,24 +9747,14 @@ } }, "node_modules/jose": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.10.3.tgz", - "integrity": "sha512-3S4wQnaoJKSAx9uHSoyf8B/lxjs1qCntHWL6wNFszJazo+FtWe+qD0zVfY0BlqJ5HHK4jcnM98k3BQzVLbzE4g==", + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } }, - "node_modules/js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10281,7 +9765,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -10312,7 +9795,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, "license": "MIT" }, "node_modules/json-parse-even-better-errors": { @@ -10325,25 +9807,21 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, "license": "MIT" }, "node_modules/jsondiffpatch": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.6.0.tgz", - "integrity": "sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.7.3.tgz", + "integrity": "sha512-zd4dqFiXSYyant2WgSXAZ9+yYqilNVvragVNkNRn2IFZKgjyULNrKRznqN4Zon0MkLueCg+3QaPVCnDAVP20OQ==", "license": "MIT", "dependencies": { - "@types/diff-match-patch": "^1.0.36", - "chalk": "^5.3.0", - "diff-match-patch": "^1.0.5" + "@dmsnell/diff-match-patch": "^1.1.0" }, "bin": { "jsondiffpatch": "bin/jsondiffpatch.js" @@ -10378,7 +9856,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -10408,7 +9885,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", @@ -10689,7 +10165,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -10718,59 +10193,8 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, "license": "MIT" }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -10919,16 +10343,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -10980,12 +10394,86 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/msw": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.14.2.tgz", + "integrity": "sha512-D2bTe0tpuf9nw4DA39wFaqUD/hRPKj0DKpo2lAqu+A47Ifg4+h0hbfn6QxVOsiUY2uhgEN6TTpGSHDsc+ysYNg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@inquirer/confirm": "^6.0.11", + "@mswjs/interceptors": "^0.41.3", + "@open-draft/deferred-promise": "^3.0.0", + "@types/statuses": "^2.0.6", + "cookie": "^1.1.1", + "graphql": "^16.13.2", + "headers-polyfill": "^5.0.1", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "path-to-regexp": "^6.3.0", + "picocolors": "^1.1.1", + "rettime": "^0.11.7", + "statuses": "^2.0.2", + "strict-event-emitter": "^0.5.1", + "tough-cookie": "^6.0.1", + "type-fest": "^5.5.0", + "until-async": "^3.0.2", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.8.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw/node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/msw/node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" + }, + "node_modules/msw/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true, - "license": "ISC" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, "node_modules/nanoid": { "version": "3.3.11", @@ -11010,7 +10498,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, "license": "MIT" }, "node_modules/negotiator": { @@ -11028,27 +10515,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "license": "MIT" }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/nodemon": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", @@ -11280,27 +10746,10 @@ "node": ">= 0.8" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, "license": "MIT", "dependencies": { "deep-is": "^0.1.3", @@ -11314,68 +10763,10 @@ "node": ">= 0.8.0" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/outvariant": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", - "dev": true, "license": "MIT" }, "node_modules/own-keys": { @@ -11400,7 +10791,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -11416,7 +10806,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -11471,7 +10860,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11481,7 +10869,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11532,9 +10919,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -11586,7 +10973,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8.0" @@ -11682,7 +11068,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -12040,12 +11425,13 @@ "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -12068,26 +11454,11 @@ "node": ">=4" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" + "node_modules/rettime": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/rettime/-/rettime-0.11.11.tgz", + "integrity": "sha512-ILJRqVWBCTlg9r42fFgwVZx1gnFAcQF8mRoMkbgQfIrjEDf9nbBFDFx00oloOa+Q869FUtaYDXZvEfnecQSCoQ==", + "license": "MIT" }, "node_modules/reusify": { "version": "1.1.0", @@ -12186,16 +11557,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12220,16 +11581,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/safe-array-concat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", @@ -12312,10 +11663,13 @@ "license": "MIT" }, "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "license": "ISC" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } }, "node_modules/scheduler": { "version": "0.23.2", @@ -12473,7 +11827,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -12486,7 +11839,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12571,6 +11923,18 @@ "dev": true, "license": "ISC" }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -12610,15 +11974,15 @@ } }, "node_modules/socket.io": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", - "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.3.tgz", + "integrity": "sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==", "license": "MIT", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", - "debug": "~4.3.2", + "debug": "~4.4.1", "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" @@ -12628,36 +11992,19 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz", + "integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==", "license": "MIT", "dependencies": { - "debug": "~4.3.4", - "ws": "~8.17.1" - } - }, - "node_modules/socket.io-adapter/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "debug": "~4.4.1", + "ws": "~8.18.3" } }, "node_modules/socket.io-adapter/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -12688,23 +12035,6 @@ "node": ">=10.0.0" } }, - "node_modules/socket.io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/sonner": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz", @@ -12781,10 +12111,9 @@ "license": "MIT" }, "node_modules/strict-event-emitter": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.4.6.tgz", - "integrity": "sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg==", - "dev": true, + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", "license": "MIT" }, "node_modules/string_decoder": { @@ -12968,7 +12297,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12978,9 +12306,9 @@ } }, "node_modules/style-mod": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", - "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz", + "integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==", "license": "MIT" }, "node_modules/style-to-js": { @@ -13011,7 +12339,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13032,12 +12359,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/tinybench": { "version": "2.9.0", @@ -13131,6 +12463,24 @@ "node": ">=14.0.0" } }, + "node_modules/tldts": { + "version": "7.0.30", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.30.tgz", + "integrity": "sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==", + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.30" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.30", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.30.tgz", + "integrity": "sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -13172,12 +12522,17 @@ "nodetouch": "bin/nodetouch.js" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true, - "license": "MIT" + "node_modules/tough-cookie": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } }, "node_modules/ts-api-utils": { "version": "2.4.0", @@ -13249,7 +12604,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" @@ -13259,13 +12613,15 @@ } }, "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, "engines": { - "node": ">=12.20" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -13366,7 +12722,7 @@ "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -13622,11 +12978,19 @@ "node": ">= 0.8" } }, + "node_modules/until-async": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/until-async/-/until-async-3.0.2.tgz", + "integrity": "sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/kettanaito" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -13663,27 +13027,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -13694,12 +13037,16 @@ } }, "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", + "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist-node/bin/uuid" } }, "node_modules/vary": { @@ -13932,42 +13279,12 @@ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", "license": "MIT" }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/web-encoding": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/web-encoding/-/web-encoding-1.1.5.tgz", - "integrity": "sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "util": "^0.12.3" - }, - "optionalDependencies": { - "@zxing/text-encoding": "0.9.0" - } - }, "node_modules/web-vitals": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", "license": "Apache-2.0" }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/whatwg-fetch": { "version": "3.6.20", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", @@ -13984,22 +13301,10 @@ "node": ">=12" } }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -14121,7 +13426,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14275,7 +13579,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -14285,9 +13588,9 @@ } }, "node_modules/zod": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.19.1.tgz", - "integrity": "sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -14305,11 +13608,16 @@ "@mui/material": "^7.3.4", "@tanstack/react-query": "5.90.20", "bignumber.js": "9.1.1", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", "react": "18.3.1", "react-dom": "18.3.1", "react-helmet-async": "^2.0.5", "react-intersection-observer": "^9.15.1", - "web-vitals": "4.2.4" + "uuid": "^14.0.0", + "web-vitals": "4.2.4", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -14321,11 +13629,11 @@ "@types/react": "18.3.12", "@types/react-dom": "18.3.6", "@vitejs/plugin-react": "^6.0.1", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", - "msw": "^1.2.5", + "msw": "^2.14.2", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", "vite": "^8.0.7", @@ -14358,103 +13666,6 @@ } } }, - "scan/frontend/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "scan/frontend/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "scan/frontend/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "scan/frontend/node_modules/msw": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/msw/-/msw-1.3.5.tgz", - "integrity": "sha512-nG3fpmBXxFbKSIdk6miPuL3KjU6WMxgoW4tG1YgnP1M+TRG3Qn7b7R0euKAHq4vpwARHb18ZyfZljSxsTnMX2w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mswjs/cookies": "^0.2.2", - "@mswjs/interceptors": "^0.17.10", - "@open-draft/until": "^1.0.3", - "@types/cookie": "^0.4.1", - "@types/js-levenshtein": "^1.1.1", - "chalk": "^4.1.1", - "chokidar": "^3.4.2", - "cookie": "^0.4.2", - "graphql": "^16.8.1", - "headers-polyfill": "3.2.5", - "inquirer": "^8.2.0", - "is-node-process": "^1.2.0", - "js-levenshtein": "^1.1.6", - "node-fetch": "^2.6.7", - "outvariant": "^1.4.0", - "path-to-regexp": "^6.3.0", - "strict-event-emitter": "^0.4.3", - "type-fest": "^2.19.0", - "yargs": "^17.3.1" - }, - "bin": { - "msw": "cli/index.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mswjs" - }, - "peerDependencies": { - "typescript": ">= 4.4.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "scan/frontend/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "dev": true, - "license": "MIT" - }, "scan/frontend/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -14585,12 +13796,16 @@ "@mui/icons-material": "^7.3.4", "@mui/material": "^7.3.4", "@tanstack/react-query": "5.90.20", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", "react": "18.3.1", "react-dom": "18.3.1", "react-helmet-async": "^2.0.5", "react-router": "^7.12.0", - "uuid": "9.0.0", - "web-vitals": "4.2.4" + "uuid": "^14.0.0", + "web-vitals": "4.2.4", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -14607,12 +13822,12 @@ "@types/react-dom": "18.3.6", "@types/uuid": "8.3.4", "@vitejs/plugin-react": "^6.0.1", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", "happy-dom": "^20.0.11", - "msw": "^1.2.5", + "msw": "^2.14.2", "prettier": "3.5.3", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", @@ -14647,103 +13862,6 @@ } } }, - "splitwell/frontend/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "splitwell/frontend/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "splitwell/frontend/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "splitwell/frontend/node_modules/msw": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/msw/-/msw-1.3.5.tgz", - "integrity": "sha512-nG3fpmBXxFbKSIdk6miPuL3KjU6WMxgoW4tG1YgnP1M+TRG3Qn7b7R0euKAHq4vpwARHb18ZyfZljSxsTnMX2w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mswjs/cookies": "^0.2.2", - "@mswjs/interceptors": "^0.17.10", - "@open-draft/until": "^1.0.3", - "@types/cookie": "^0.4.1", - "@types/js-levenshtein": "^1.1.1", - "chalk": "^4.1.1", - "chokidar": "^3.4.2", - "cookie": "^0.4.2", - "graphql": "^16.8.1", - "headers-polyfill": "3.2.5", - "inquirer": "^8.2.0", - "is-node-process": "^1.2.0", - "js-levenshtein": "^1.1.6", - "node-fetch": "^2.6.7", - "outvariant": "^1.4.0", - "path-to-regexp": "^6.3.0", - "strict-event-emitter": "^0.4.3", - "type-fest": "^2.19.0", - "yargs": "^17.3.1" - }, - "bin": { - "msw": "cli/index.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mswjs" - }, - "peerDependencies": { - "typescript": ">= 4.4.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "splitwell/frontend/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "dev": true, - "license": "MIT" - }, "splitwell/frontend/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -14877,6 +13995,9 @@ "@mui/x-date-pickers": "^8.14.1", "@tanstack/react-form": "^1.23.0", "dayjs": "^1.11.9", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", "oidc-client-ts": "2.2.1", "react": "18.3.1", "react-dom": "18.3.1", @@ -14885,8 +14006,9 @@ "react-json-pretty": "2.2.0", "react-oidc-context": "2.2.2", "sonner": "^2.0.7", - "uuid": "9.0.0", - "web-vitals": "4.2.4" + "uuid": "^14.0.0", + "web-vitals": "4.2.4", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -14904,13 +14026,13 @@ "@types/uuid": "8.3.4", "@vitejs/plugin-react": "^6.0.1", "@vitest/ui": "^3.1.2", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", "happy-dom": "^20.0.11", "html-format": "^1.1.7", - "msw": "^1.2.5", + "msw": "^2.14.2", "prettier": "3.5.3", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", @@ -14945,103 +14067,6 @@ } } }, - "sv/frontend/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "sv/frontend/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "sv/frontend/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "sv/frontend/node_modules/msw": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/msw/-/msw-1.3.5.tgz", - "integrity": "sha512-nG3fpmBXxFbKSIdk6miPuL3KjU6WMxgoW4tG1YgnP1M+TRG3Qn7b7R0euKAHq4vpwARHb18ZyfZljSxsTnMX2w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mswjs/cookies": "^0.2.2", - "@mswjs/interceptors": "^0.17.10", - "@open-draft/until": "^1.0.3", - "@types/cookie": "^0.4.1", - "@types/js-levenshtein": "^1.1.1", - "chalk": "^4.1.1", - "chokidar": "^3.4.2", - "cookie": "^0.4.2", - "graphql": "^16.8.1", - "headers-polyfill": "3.2.5", - "inquirer": "^8.2.0", - "is-node-process": "^1.2.0", - "js-levenshtein": "^1.1.6", - "node-fetch": "^2.6.7", - "outvariant": "^1.4.0", - "path-to-regexp": "^6.3.0", - "strict-event-emitter": "^0.4.3", - "type-fest": "^2.19.0", - "yargs": "^17.3.1" - }, - "bin": { - "msw": "cli/index.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mswjs" - }, - "peerDependencies": { - "typescript": ">= 4.4.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "sv/frontend/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "dev": true, - "license": "MIT" - }, "sv/frontend/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -15304,9 +14329,14 @@ "@mui/material": "^7.3.4", "@tanstack/react-query": "5.90.20", "bignumber.js": "9.1.1", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", "react": "18.3.1", "react-dom": "18.3.1", - "react-helmet-async": "^2.0.5" + "react-helmet-async": "^2.0.5", + "uuid": "^14.0.0", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -15324,7 +14354,7 @@ "@typescript-eslint/eslint-plugin": "8.29.1", "@typescript-eslint/parser": "8.29.1", "@vitejs/plugin-react": "^6.0.1", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-config-prettier": "10.1.1", "eslint-plugin-import": "2.31.0", "eslint-plugin-jsx-a11y": "6.10.2", @@ -15332,7 +14362,7 @@ "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", "happy-dom": "^20.0.11", - "msw": "^1.2.5", + "msw": "^2.14.2", "prettier": "3.5.3", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", @@ -15367,103 +14397,6 @@ } } }, - "wallet/frontend/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "wallet/frontend/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "wallet/frontend/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "wallet/frontend/node_modules/msw": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/msw/-/msw-1.3.5.tgz", - "integrity": "sha512-nG3fpmBXxFbKSIdk6miPuL3KjU6WMxgoW4tG1YgnP1M+TRG3Qn7b7R0euKAHq4vpwARHb18ZyfZljSxsTnMX2w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mswjs/cookies": "^0.2.2", - "@mswjs/interceptors": "^0.17.10", - "@open-draft/until": "^1.0.3", - "@types/cookie": "^0.4.1", - "@types/js-levenshtein": "^1.1.1", - "chalk": "^4.1.1", - "chokidar": "^3.4.2", - "cookie": "^0.4.2", - "graphql": "^16.8.1", - "headers-polyfill": "3.2.5", - "inquirer": "^8.2.0", - "is-node-process": "^1.2.0", - "js-levenshtein": "^1.1.6", - "node-fetch": "^2.6.7", - "outvariant": "^1.4.0", - "path-to-regexp": "^6.3.0", - "strict-event-emitter": "^0.4.3", - "type-fest": "^2.19.0", - "yargs": "^17.3.1" - }, - "bin": { - "msw": "cli/index.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mswjs" - }, - "peerDependencies": { - "typescript": ">= 4.4.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "wallet/frontend/node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "dev": true, - "license": "MIT" - }, "wallet/frontend/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", diff --git a/apps/package.json b/apps/package.json index 3483076b0f..b3e1b1ce3b 100644 --- a/apps/package.json +++ b/apps/package.json @@ -29,6 +29,14 @@ "@daml.js/splice-wallet-payments": "file:common/frontend/daml.js/splice-wallet-payments-0.1.18", "@daml.js/splitwell": "file:common/frontend/daml.js/splitwell-0.1.19", "@daml/types": "^3.4.11", - "xunit-viewer": "^10.6.1" + "@dmsnell/diff-match-patch": "^1.1.0", + "dompurify": "^3.4.2", + "eslint": "^9.39.4", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", + "msw": "^2.14.2", + "uuid": "^14.0.0", + "xunit-viewer": "^10.6.1", + "zod": "^3.25.76" } } diff --git a/apps/scan/frontend/package.json b/apps/scan/frontend/package.json index 78b8f69425..3de70c5b35 100644 --- a/apps/scan/frontend/package.json +++ b/apps/scan/frontend/package.json @@ -16,17 +16,22 @@ "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@lfdecentralizedtrust/token-metadata-openapi": "file:../../../token-standard/splice-api-token-metadata-v1/openapi-ts-client", "@lfdecentralizedtrust/splice-common-frontend": "0.1.0", + "@lfdecentralizedtrust/token-metadata-openapi": "file:../../../token-standard/splice-api-token-metadata-v1/openapi-ts-client", "@mui/icons-material": "^7.3.4", "@mui/material": "^7.3.4", "@tanstack/react-query": "5.90.20", "bignumber.js": "9.1.1", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", "react": "18.3.1", "react-dom": "18.3.1", "react-helmet-async": "^2.0.5", "react-intersection-observer": "^9.15.1", - "web-vitals": "4.2.4" + "uuid": "^14.0.0", + "web-vitals": "4.2.4", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -38,11 +43,11 @@ "@types/react": "18.3.12", "@types/react-dom": "18.3.6", "@vitejs/plugin-react": "^6.0.1", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", - "msw": "^1.2.5", + "msw": "^2.14.2", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", "vite": "^8.0.7", diff --git a/apps/scan/frontend/src/__tests__/mocks/browser.ts b/apps/scan/frontend/src/__tests__/mocks/browser.ts index 6e7445f049..60835386b7 100644 --- a/apps/scan/frontend/src/__tests__/mocks/browser.ts +++ b/apps/scan/frontend/src/__tests__/mocks/browser.ts @@ -1,6 +1,6 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { setupWorker, SetupWorker } from 'msw'; +import { setupWorker, SetupWorker } from 'msw/browser'; import { buildScanMock } from './handlers/scan-api'; diff --git a/apps/scan/frontend/src/__tests__/mocks/handlers/scan-api.ts b/apps/scan/frontend/src/__tests__/mocks/handlers/scan-api.ts index ab580ecb7f..a5528c53fc 100644 --- a/apps/scan/frontend/src/__tests__/mocks/handlers/scan-api.ts +++ b/apps/scan/frontend/src/__tests__/mocks/handlers/scan-api.ts @@ -4,7 +4,7 @@ import { validatorLicensesHandler, dsoInfoHandler, } from '@lfdecentralizedtrust/splice-common-test-handlers'; -import { RestHandler, rest } from 'msw'; +import { http, HttpHandler, HttpResponse } from 'msw'; import { ErrorResponse, GetAmuletRulesResponse, @@ -23,425 +23,415 @@ import { Instrument } from '@lfdecentralizedtrust/token-metadata-openapi'; const amuletNameServiceAcronym = config.spliceInstanceNames.nameServiceNameAcronym; -export const buildScanMock = (baseScanUrl: string): RestHandler[] => { +export const buildScanMock = (baseScanUrl: string): HttpHandler[] => { const scanUrl = `${baseScanUrl}/api/scan`; return [ - rest.get(`${scanUrl}/v0/feature-support`, (_, res, ctx) => { - return res(ctx.json({})); + http.get(`${scanUrl}/v0/feature-support`, () => { + return HttpResponse.json({}); }), dsoInfoHandler(scanUrl), - rest.get(`${scanUrl}/v0/dso-party-id`, (_, res, ctx) => { - return res( - ctx.json({ - dso_party_id: 'DSO::1220809612f787469c92b924ad1d32f1cbc0bdbd4eeda55a50469250bcf64b8becf2', - }) - ); + http.get(`${scanUrl}/v0/dso-party-id`, () => { + return HttpResponse.json({ + dso_party_id: 'DSO::1220809612f787469c92b924ad1d32f1cbc0bdbd4eeda55a50469250bcf64b8becf2', + }); }), - rest.get(`${baseScanUrl}/registry/metadata/v1/instruments/Amulet`, (_, res, ctx) => { - return res( - ctx.json({ - id: 'Amulet', - name: 'Amulet', - symbol: 'AMT', - totalSupply: '123', - totalSupplyAsOf: new Date(), - decimals: 10, - supportedApis: {}, - }) - ); + http.get(`${baseScanUrl}/registry/metadata/v1/instruments/Amulet`, () => { + return HttpResponse.json({ + id: 'Amulet', + name: 'Amulet', + symbol: 'AMT', + totalSupply: '123', + totalSupplyAsOf: new Date(), + decimals: 10, + supportedApis: {}, + }); }), - rest.post(`${scanUrl}/v0/open-and-issuing-mining-rounds`, (_, res, ctx) => { - return res( - ctx.json({ - time_to_live_in_microseconds: 600000000, - open_mining_rounds: { - '009a934375bd5cc210ef43bac9f39c30e0217508352736292e0c9a01457bced1b8ca101220a31c4383e5b082d5db639bb177c4827796043b896c84cab370412b33a3ca1a21': - { - contract: { - template_id: - '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:OpenMiningRound', - contract_id: - '009a934375bd5cc210ef43bac9f39c30e0217508352736292e0c9a01457bced1b8ca101220a31c4383e5b082d5db639bb177c4827796043b896c84cab370412b33a3ca1a21', - payload: { - dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', - tickDuration: { - microseconds: '600000000', - }, - issuingFor: { - microseconds: '7800000000', + http.post(`${scanUrl}/v0/open-and-issuing-mining-rounds`, () => { + return HttpResponse.json({ + time_to_live_in_microseconds: 600000000, + open_mining_rounds: { + '009a934375bd5cc210ef43bac9f39c30e0217508352736292e0c9a01457bced1b8ca101220a31c4383e5b082d5db639bb177c4827796043b896c84cab370412b33a3ca1a21': + { + contract: { + template_id: + '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:OpenMiningRound', + contract_id: + '009a934375bd5cc210ef43bac9f39c30e0217508352736292e0c9a01457bced1b8ca101220a31c4383e5b082d5db639bb177c4827796043b896c84cab370412b33a3ca1a21', + payload: { + dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + tickDuration: { + microseconds: '600000000', + }, + issuingFor: { + microseconds: '7800000000', + }, + amuletPrice: '0.005', + issuanceConfig: { + validatorRewardPercentage: '0.05', + unfeaturedAppRewardCap: '0.6', + appRewardPercentage: '0.15', + featuredAppRewardCap: '100.0', + amuletToIssuePerYear: '40000000000.0', + validatorRewardCap: '0.2', + optValidatorFaucetCap: '2.85', + optDevelopmentFundPercentage: '0.05', + }, + opensAt: '2025-02-03T13:43:37.895871Z', + transferConfigUsd: { + holdingFee: { + rate: '0.0000190259', }, - amuletPrice: '0.005', - issuanceConfig: { - validatorRewardPercentage: '0.05', - unfeaturedAppRewardCap: '0.6', - appRewardPercentage: '0.15', - featuredAppRewardCap: '100.0', - amuletToIssuePerYear: '40000000000.0', - validatorRewardCap: '0.2', - optValidatorFaucetCap: '2.85', - optDevelopmentFundPercentage: '0.05', + extraFeaturedAppRewardAmount: '1.0', + maxNumInputs: '100', + lockHolderFee: { + fee: '0.005', }, - opensAt: '2025-02-03T13:43:37.895871Z', - transferConfigUsd: { - holdingFee: { - rate: '0.0000190259', - }, - extraFeaturedAppRewardAmount: '1.0', - maxNumInputs: '100', - lockHolderFee: { - fee: '0.005', - }, - createFee: { - fee: '0.03', - }, - maxNumLockHolders: '50', - transferFee: { - initialRate: '0.01', - steps: [ - { - _1: '100.0', - _2: '0.001', - }, - { - _1: '1000.0', - _2: '0.0001', - }, - { - _1: '1000000.0', - _2: '0.00001', - }, - ], - }, - maxNumOutputs: '100', + createFee: { + fee: '0.03', }, - targetClosesAt: '2025-02-03T14:03:37.895871Z', - round: { - number: '13', + maxNumLockHolders: '50', + transferFee: { + initialRate: '0.01', + steps: [ + { + _1: '100.0', + _2: '0.001', + }, + { + _1: '1000.0', + _2: '0.0001', + }, + { + _1: '1000000.0', + _2: '0.00001', + }, + ], }, + maxNumOutputs: '100', + }, + targetClosesAt: '2025-02-03T14:03:37.895871Z', + round: { + number: '13', }, - created_event_blob: - 'CgMyLjESnAcKRQCak0N1vVzCEO9DusnznDDgIXUINSc2KS4MmgFFe87RuMoQEiCjHEOD5bCC1dtjm7F3xIJ3lgQ7iWyEyrNwQSszo8oaIRINc3BsaWNlLWFtdWxldBpiCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGg9PcGVuTWluaW5nUm91bmQi3wRq3AQKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgaChAKDjIMMC4wMDUwMDAwMDAwCgsKCSm//1gUPS0GAAoLCgkpv4vfWz0tBgAKDgoMagoKCAoGGIC41I46CpsCCpgCapUCChYKFGoSChAKDjIMMC4wMzAwMDAwMDAwChYKFGoSChAKDjIMMC4wMDAwMTkwMjU5CqQBCqEBap4BChAKDjIMMC4wMTAwMDAwMDAwCokBCoYBWoMBCihqJgoSChAyDjEwMC4wMDAwMDAwMDAwChAKDjIMMC4wMDEwMDAwMDAwCilqJwoTChEyDzEwMDAuMDAwMDAwMDAwMAoQCg4yDDAuMDAwMTAwMDAwMAosaioKFgoUMhIxMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjAwMDAxMDAwMDAKFgoUahIKEAoOMgwwLjAwNTAwMDAwMDAKEAoOMgwxLjAwMDAwMDAwMDAKBQoDGMgBCgUKAxjIAQoECgIYZAqUAQqRAWqOAQoaChgyFjQwMDAwMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjA1MDAwMDAwMDAKEAoOMgwwLjE1MDAwMDAwMDAKEAoOMgwwLjIwMDAwMDAwMDAKEgoQMg4xMDAuMDAwMDAwMDAwMAoQCg4yDDAuNjAwMDAwMDAwMAoUChJSEAoOMgwyLjg1MDAwMDAwMDAKDgoMagoKCAoGGICYmrwEKklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1Ob+5lfA8LQYAQioKJgokCAESII1Y253JV9bGtIGPHgORo5ifHeKP/DyNl1FPeuMkEHhVEB4=', - created_at: '2025-02-03T13:33:37.895871Z', }, - domain_id: - 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + created_event_blob: + 'CgMyLjESnAcKRQCak0N1vVzCEO9DusnznDDgIXUINSc2KS4MmgFFe87RuMoQEiCjHEOD5bCC1dtjm7F3xIJ3lgQ7iWyEyrNwQSszo8oaIRINc3BsaWNlLWFtdWxldBpiCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGg9PcGVuTWluaW5nUm91bmQi3wRq3AQKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgaChAKDjIMMC4wMDUwMDAwMDAwCgsKCSm//1gUPS0GAAoLCgkpv4vfWz0tBgAKDgoMagoKCAoGGIC41I46CpsCCpgCapUCChYKFGoSChAKDjIMMC4wMzAwMDAwMDAwChYKFGoSChAKDjIMMC4wMDAwMTkwMjU5CqQBCqEBap4BChAKDjIMMC4wMTAwMDAwMDAwCokBCoYBWoMBCihqJgoSChAyDjEwMC4wMDAwMDAwMDAwChAKDjIMMC4wMDEwMDAwMDAwCilqJwoTChEyDzEwMDAuMDAwMDAwMDAwMAoQCg4yDDAuMDAwMTAwMDAwMAosaioKFgoUMhIxMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjAwMDAxMDAwMDAKFgoUahIKEAoOMgwwLjAwNTAwMDAwMDAKEAoOMgwxLjAwMDAwMDAwMDAKBQoDGMgBCgUKAxjIAQoECgIYZAqUAQqRAWqOAQoaChgyFjQwMDAwMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjA1MDAwMDAwMDAKEAoOMgwwLjE1MDAwMDAwMDAKEAoOMgwwLjIwMDAwMDAwMDAKEgoQMg4xMDAuMDAwMDAwMDAwMAoQCg4yDDAuNjAwMDAwMDAwMAoUChJSEAoOMgwyLjg1MDAwMDAwMDAKDgoMagoKCAoGGICYmrwEKklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1Ob+5lfA8LQYAQioKJgokCAESII1Y253JV9bGtIGPHgORo5ifHeKP/DyNl1FPeuMkEHhVEB4=', + created_at: '2025-02-03T13:33:37.895871Z', }, - '00b8d18fce8ca1877853768fa3bf54054b960f76a85e2384d446ccdc5d7291ce3dca101220b0d8404b000a47a9b3ad0c5bab2b033ce85aeeb975844bafffb96f51209a3280': - { - contract: { - template_id: - '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:OpenMiningRound', - contract_id: - '00b8d18fce8ca1877853768fa3bf54054b960f76a85e2384d446ccdc5d7291ce3dca101220b0d8404b000a47a9b3ad0c5bab2b033ce85aeeb975844bafffb96f51209a3280', - payload: { - dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', - tickDuration: { - microseconds: '600000000', - }, - issuingFor: { - microseconds: '8400000000', + domain_id: + 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + }, + '00b8d18fce8ca1877853768fa3bf54054b960f76a85e2384d446ccdc5d7291ce3dca101220b0d8404b000a47a9b3ad0c5bab2b033ce85aeeb975844bafffb96f51209a3280': + { + contract: { + template_id: + '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:OpenMiningRound', + contract_id: + '00b8d18fce8ca1877853768fa3bf54054b960f76a85e2384d446ccdc5d7291ce3dca101220b0d8404b000a47a9b3ad0c5bab2b033ce85aeeb975844bafffb96f51209a3280', + payload: { + dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + tickDuration: { + microseconds: '600000000', + }, + issuingFor: { + microseconds: '8400000000', + }, + amuletPrice: '0.005', + issuanceConfig: { + validatorRewardPercentage: '0.05', + unfeaturedAppRewardCap: '0.6', + appRewardPercentage: '0.15', + featuredAppRewardCap: '100.0', + amuletToIssuePerYear: '40000000000.0', + validatorRewardCap: '0.2', + optValidatorFaucetCap: '2.85', + optDevelopmentFundPercentage: '0.05', + }, + opensAt: '2025-02-03T13:54:09.430298Z', + transferConfigUsd: { + holdingFee: { + rate: '0.0000190259', }, - amuletPrice: '0.005', - issuanceConfig: { - validatorRewardPercentage: '0.05', - unfeaturedAppRewardCap: '0.6', - appRewardPercentage: '0.15', - featuredAppRewardCap: '100.0', - amuletToIssuePerYear: '40000000000.0', - validatorRewardCap: '0.2', - optValidatorFaucetCap: '2.85', - optDevelopmentFundPercentage: '0.05', + extraFeaturedAppRewardAmount: '1.0', + maxNumInputs: '100', + lockHolderFee: { + fee: '0.005', }, - opensAt: '2025-02-03T13:54:09.430298Z', - transferConfigUsd: { - holdingFee: { - rate: '0.0000190259', - }, - extraFeaturedAppRewardAmount: '1.0', - maxNumInputs: '100', - lockHolderFee: { - fee: '0.005', - }, - createFee: { - fee: '0.03', - }, - maxNumLockHolders: '50', - transferFee: { - initialRate: '0.01', - steps: [ - { - _1: '100.0', - _2: '0.001', - }, - { - _1: '1000.0', - _2: '0.0001', - }, - { - _1: '1000000.0', - _2: '0.00001', - }, - ], - }, - maxNumOutputs: '100', + createFee: { + fee: '0.03', }, - targetClosesAt: '2025-02-03T14:14:09.430298Z', - round: { - number: '14', + maxNumLockHolders: '50', + transferFee: { + initialRate: '0.01', + steps: [ + { + _1: '100.0', + _2: '0.001', + }, + { + _1: '1000.0', + _2: '0.0001', + }, + { + _1: '1000000.0', + _2: '0.00001', + }, + ], }, + maxNumOutputs: '100', + }, + targetClosesAt: '2025-02-03T14:14:09.430298Z', + round: { + number: '14', }, - created_event_blob: - 'CgMyLjESnAcKRQC40Y/OjKGHeFN2j6O/VAVLlg92qF4jhNRGzNxdcpHOPcoQEiCw2EBLAApHqbOtDFurKwM86FruuXWES6//uW9RIJoygBINc3BsaWNlLWFtdWxldBpiCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGg9PcGVuTWluaW5nUm91bmQi3wRq3AQKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgcChAKDjIMMC4wMDUwMDAwMDAwCgsKCSkac/05PS0GAAoLCgkpGv+DgT0tBgAKDgoMagoKCAoGGIDQ7so+CpsCCpgCapUCChYKFGoSChAKDjIMMC4wMzAwMDAwMDAwChYKFGoSChAKDjIMMC4wMDAwMTkwMjU5CqQBCqEBap4BChAKDjIMMC4wMTAwMDAwMDAwCokBCoYBWoMBCihqJgoSChAyDjEwMC4wMDAwMDAwMDAwChAKDjIMMC4wMDEwMDAwMDAwCilqJwoTChEyDzEwMDAuMDAwMDAwMDAwMAoQCg4yDDAuMDAwMTAwMDAwMAosaioKFgoUMhIxMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjAwMDAxMDAwMDAKFgoUahIKEAoOMgwwLjAwNTAwMDAwMDAKEAoOMgwxLjAwMDAwMDAwMDAKBQoDGMgBCgUKAxjIAQoECgIYZAqUAQqRAWqOAQoaChgyFjQwMDAwMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjA1MDAwMDAwMDAKEAoOMgwwLjE1MDAwMDAwMDAKEAoOMgwwLjIwMDAwMDAwMDAKEgoQMg4xMDAuMDAwMDAwMDAwMAoQCg4yDDAuNjAwMDAwMDAwMAoUChJSEAoOMgwyLjg1MDAwMDAwMDAKDgoMagoKCAoGGICYmrwEKklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1ORotOhY9LQYAQioKJgokCAESIGnxQ/xls3iV03z1c/PyqX/D+pEGpVzy0O2313jozuBcEB4=', - created_at: '2025-02-03T13:44:09.430298Z', }, - domain_id: - 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + created_event_blob: + 'CgMyLjESnAcKRQC40Y/OjKGHeFN2j6O/VAVLlg92qF4jhNRGzNxdcpHOPcoQEiCw2EBLAApHqbOtDFurKwM86FruuXWES6//uW9RIJoygBINc3BsaWNlLWFtdWxldBpiCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGg9PcGVuTWluaW5nUm91bmQi3wRq3AQKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgcChAKDjIMMC4wMDUwMDAwMDAwCgsKCSkac/05PS0GAAoLCgkpGv+DgT0tBgAKDgoMagoKCAoGGIDQ7so+CpsCCpgCapUCChYKFGoSChAKDjIMMC4wMzAwMDAwMDAwChYKFGoSChAKDjIMMC4wMDAwMTkwMjU5CqQBCqEBap4BChAKDjIMMC4wMTAwMDAwMDAwCokBCoYBWoMBCihqJgoSChAyDjEwMC4wMDAwMDAwMDAwChAKDjIMMC4wMDEwMDAwMDAwCilqJwoTChEyDzEwMDAuMDAwMDAwMDAwMAoQCg4yDDAuMDAwMTAwMDAwMAosaioKFgoUMhIxMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjAwMDAxMDAwMDAKFgoUahIKEAoOMgwwLjAwNTAwMDAwMDAKEAoOMgwxLjAwMDAwMDAwMDAKBQoDGMgBCgUKAxjIAQoECgIYZAqUAQqRAWqOAQoaChgyFjQwMDAwMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjA1MDAwMDAwMDAKEAoOMgwwLjE1MDAwMDAwMDAKEAoOMgwwLjIwMDAwMDAwMDAKEgoQMg4xMDAuMDAwMDAwMDAwMAoQCg4yDDAuNjAwMDAwMDAwMAoUChJSEAoOMgwyLjg1MDAwMDAwMDAKDgoMagoKCAoGGICYmrwEKklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1ORotOhY9LQYAQioKJgokCAESIGnxQ/xls3iV03z1c/PyqX/D+pEGpVzy0O2313jozuBcEB4=', + created_at: '2025-02-03T13:44:09.430298Z', }, - '00c57f207d5cba837f5d5c2c5d98cb39d8e00a5a8722d3d686b95d056e3563f69bca1012201ef22e3a580e785ac39844c13365083ce8e888b7335cec0e480945e13edb5312': - { - contract: { - template_id: - '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:OpenMiningRound', - contract_id: - '00c57f207d5cba837f5d5c2c5d98cb39d8e00a5a8722d3d686b95d056e3563f69bca1012201ef22e3a580e785ac39844c13365083ce8e888b7335cec0e480945e13edb5312', - payload: { - dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', - tickDuration: { - microseconds: '600000000', - }, - issuingFor: { - microseconds: '9000000000', + domain_id: + 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + }, + '00c57f207d5cba837f5d5c2c5d98cb39d8e00a5a8722d3d686b95d056e3563f69bca1012201ef22e3a580e785ac39844c13365083ce8e888b7335cec0e480945e13edb5312': + { + contract: { + template_id: + '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:OpenMiningRound', + contract_id: + '00c57f207d5cba837f5d5c2c5d98cb39d8e00a5a8722d3d686b95d056e3563f69bca1012201ef22e3a580e785ac39844c13365083ce8e888b7335cec0e480945e13edb5312', + payload: { + dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + tickDuration: { + microseconds: '600000000', + }, + issuingFor: { + microseconds: '9000000000', + }, + amuletPrice: '0.005', + issuanceConfig: { + validatorRewardPercentage: '0.05', + unfeaturedAppRewardCap: '0.6', + appRewardPercentage: '0.15', + featuredAppRewardCap: '100.0', + amuletToIssuePerYear: '40000000000.0', + validatorRewardCap: '0.2', + optValidatorFaucetCap: '2.85', + optDevelopmentFundPercentage: '0.05', + }, + opensAt: '2025-02-03T14:04:37.024279Z', + transferConfigUsd: { + holdingFee: { + rate: '0.0000190259', }, - amuletPrice: '0.005', - issuanceConfig: { - validatorRewardPercentage: '0.05', - unfeaturedAppRewardCap: '0.6', - appRewardPercentage: '0.15', - featuredAppRewardCap: '100.0', - amuletToIssuePerYear: '40000000000.0', - validatorRewardCap: '0.2', - optValidatorFaucetCap: '2.85', - optDevelopmentFundPercentage: '0.05', + extraFeaturedAppRewardAmount: '1.0', + maxNumInputs: '100', + lockHolderFee: { + fee: '0.005', }, - opensAt: '2025-02-03T14:04:37.024279Z', - transferConfigUsd: { - holdingFee: { - rate: '0.0000190259', - }, - extraFeaturedAppRewardAmount: '1.0', - maxNumInputs: '100', - lockHolderFee: { - fee: '0.005', - }, - createFee: { - fee: '0.03', - }, - maxNumLockHolders: '50', - transferFee: { - initialRate: '0.01', - steps: [ - { - _1: '100.0', - _2: '0.001', - }, - { - _1: '1000.0', - _2: '0.0001', - }, - { - _1: '1000000.0', - _2: '0.00001', - }, - ], - }, - maxNumOutputs: '100', + createFee: { + fee: '0.03', }, - targetClosesAt: '2025-02-03T14:24:37.024279Z', - round: { - number: '15', + maxNumLockHolders: '50', + transferFee: { + initialRate: '0.01', + steps: [ + { + _1: '100.0', + _2: '0.001', + }, + { + _1: '1000.0', + _2: '0.0001', + }, + { + _1: '1000000.0', + _2: '0.00001', + }, + ], }, + maxNumOutputs: '100', + }, + targetClosesAt: '2025-02-03T14:24:37.024279Z', + round: { + number: '15', }, - created_event_blob: - 'CgMyLjESnAcKRQDFfyB9XLqDf11cLF2YyznY4ApahyLT1oa5XQVuNWP2m8oQEiAe8i46WA54WsOYRMEzZQg86OiItzNc7A5ICUXhPttTEhINc3BsaWNlLWFtdWxldBpiCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGg9PcGVuTWluaW5nUm91bmQi3wRq3AQKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgeChAKDjIMMC4wMDUwMDAwMDAwCgsKCSkXxmVfPS0GAAoLCgkpF1Lspj0tBgAKDgoMagoKCAoGGIDoiIdDCpsCCpgCapUCChYKFGoSChAKDjIMMC4wMzAwMDAwMDAwChYKFGoSChAKDjIMMC4wMDAwMTkwMjU5CqQBCqEBap4BChAKDjIMMC4wMTAwMDAwMDAwCokBCoYBWoMBCihqJgoSChAyDjEwMC4wMDAwMDAwMDAwChAKDjIMMC4wMDEwMDAwMDAwCilqJwoTChEyDzEwMDAuMDAwMDAwMDAwMAoQCg4yDDAuMDAwMTAwMDAwMAosaioKFgoUMhIxMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjAwMDAxMDAwMDAKFgoUahIKEAoOMgwwLjAwNTAwMDAwMDAKEAoOMgwxLjAwMDAwMDAwMDAKBQoDGMgBCgUKAxjIAQoECgIYZAqUAQqRAWqOAQoaChgyFjQwMDAwMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjA1MDAwMDAwMDAKEAoOMgwwLjE1MDAwMDAwMDAKEAoOMgwwLjIwMDAwMDAwMDAKEgoQMg4xMDAuMDAwMDAwMDAwMAoQCg4yDDAuNjAwMDAwMDAwMAoUChJSEAoOMgwyLjg1MDAwMDAwMDAKDgoMagoKCAoGGICYmrwEKklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1OReAojs9LQYAQioKJgokCAESINmB+Ya7MKDFsouNqAfzkCN1IsjBN+j1D24h8GE6/KQaEB4=', - created_at: '2025-02-03T13:54:37.024279Z', }, - domain_id: - 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + created_event_blob: + 'CgMyLjESnAcKRQDFfyB9XLqDf11cLF2YyznY4ApahyLT1oa5XQVuNWP2m8oQEiAe8i46WA54WsOYRMEzZQg86OiItzNc7A5ICUXhPttTEhINc3BsaWNlLWFtdWxldBpiCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGg9PcGVuTWluaW5nUm91bmQi3wRq3AQKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgeChAKDjIMMC4wMDUwMDAwMDAwCgsKCSkXxmVfPS0GAAoLCgkpF1Lspj0tBgAKDgoMagoKCAoGGIDoiIdDCpsCCpgCapUCChYKFGoSChAKDjIMMC4wMzAwMDAwMDAwChYKFGoSChAKDjIMMC4wMDAwMTkwMjU5CqQBCqEBap4BChAKDjIMMC4wMTAwMDAwMDAwCokBCoYBWoMBCihqJgoSChAyDjEwMC4wMDAwMDAwMDAwChAKDjIMMC4wMDEwMDAwMDAwCilqJwoTChEyDzEwMDAuMDAwMDAwMDAwMAoQCg4yDDAuMDAwMTAwMDAwMAosaioKFgoUMhIxMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjAwMDAxMDAwMDAKFgoUahIKEAoOMgwwLjAwNTAwMDAwMDAKEAoOMgwxLjAwMDAwMDAwMDAKBQoDGMgBCgUKAxjIAQoECgIYZAqUAQqRAWqOAQoaChgyFjQwMDAwMDAwMDAwLjAwMDAwMDAwMDAKEAoOMgwwLjA1MDAwMDAwMDAKEAoOMgwwLjE1MDAwMDAwMDAKEAoOMgwwLjIwMDAwMDAwMDAKEgoQMg4xMDAuMDAwMDAwMDAwMAoQCg4yDDAuNjAwMDAwMDAwMAoUChJSEAoOMgwyLjg1MDAwMDAwMDAKDgoMagoKCAoGGICYmrwEKklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1OReAojs9LQYAQioKJgokCAESINmB+Ya7MKDFsouNqAfzkCN1IsjBN+j1D24h8GE6/KQaEB4=', + created_at: '2025-02-03T13:54:37.024279Z', }, - }, - issuing_mining_rounds: { - '0072433d5d987da2d3e24e87b9e2de0b1acdee81a111654ae99f2d8711fd9c9cc8ca1012204eb8c7877fe0490cacad4e31d5e96345d492c865664f75c0bb090b5b6f4c4412': - { - contract: { - template_id: - '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:IssuingMiningRound', - contract_id: - '0072433d5d987da2d3e24e87b9e2de0b1acdee81a111654ae99f2d8711fd9c9cc8ca1012204eb8c7877fe0490cacad4e31d5e96345d492c865664f75c0bb090b5b6f4c4412', - payload: { - dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', - optIssuancePerValidatorFaucetCoupon: '570.0', - issuancePerFeaturedAppRewardCoupon: '100.0', - opensAt: '2025-02-03T13:43:53.180125Z', - issuancePerSvRewardCoupon: '30.4414003044', - targetClosesAt: '2025-02-03T14:03:53.180125Z', - issuancePerUnfeaturedAppRewardCoupon: '0.6', - round: { - number: '10', - }, - issuancePerValidatorRewardCoupon: '0.2', + domain_id: + 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + }, + }, + issuing_mining_rounds: { + '0072433d5d987da2d3e24e87b9e2de0b1acdee81a111654ae99f2d8711fd9c9cc8ca1012204eb8c7877fe0490cacad4e31d5e96345d492c865664f75c0bb090b5b6f4c4412': + { + contract: { + template_id: + '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:IssuingMiningRound', + contract_id: + '0072433d5d987da2d3e24e87b9e2de0b1acdee81a111654ae99f2d8711fd9c9cc8ca1012204eb8c7877fe0490cacad4e31d5e96345d492c865664f75c0bb090b5b6f4c4412', + payload: { + dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + optIssuancePerValidatorFaucetCoupon: '570.0', + issuancePerFeaturedAppRewardCoupon: '100.0', + opensAt: '2025-02-03T13:43:53.180125Z', + issuancePerSvRewardCoupon: '30.4414003044', + targetClosesAt: '2025-02-03T14:03:53.180125Z', + issuancePerUnfeaturedAppRewardCoupon: '0.6', + round: { + number: '10', }, - created_event_blob: - 'CgMyLjESmwQKRQByQz1dmH2i0+JOh7ni3gsaze6BoRFlSumfLYcR/ZycyMoQEiBOuMeHf+BJDKytTjHV6WNF1JLIZWZPdcC7CQtbb0xEEhINc3BsaWNlLWFtdWxldBplCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGhJJc3N1aW5nTWluaW5nUm91bmQi2wFq2AEKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgUChAKDjIMMC4yMDAwMDAwMDAwChIKEDIOMTAwLjAwMDAwMDAwMDAKEAoOMgwwLjYwMDAwMDAwMDAKEQoPMg0zMC40NDE0MDAzMDQ0CgsKCSndN0IVPS0GAAoLCgkp3cPIXD0tBgAKFgoUUhIKEDIONTcwLjAwMDAwMDAwMDAqSURTTzo6MTIyMDIzZDg0ZWI0MDE5ZWE3NzVmMzY0NTU0YzM1NThjYTc5ZDQyZGUxMjk4ODRhZGNmMWEyNTk4MWNlOGZkZmZhZTU53fF+8TwtBgBCKgomCiQIARIgsKDXx/J5/37sWqsgLM30Alfzt09dqWCFmp3HzTZItL8QHg==', - created_at: '2025-02-03T13:33:53.180125Z', + issuancePerValidatorRewardCoupon: '0.2', }, - domain_id: - 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + created_event_blob: + 'CgMyLjESmwQKRQByQz1dmH2i0+JOh7ni3gsaze6BoRFlSumfLYcR/ZycyMoQEiBOuMeHf+BJDKytTjHV6WNF1JLIZWZPdcC7CQtbb0xEEhINc3BsaWNlLWFtdWxldBplCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGhJJc3N1aW5nTWluaW5nUm91bmQi2wFq2AEKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgUChAKDjIMMC4yMDAwMDAwMDAwChIKEDIOMTAwLjAwMDAwMDAwMDAKEAoOMgwwLjYwMDAwMDAwMDAKEQoPMg0zMC40NDE0MDAzMDQ0CgsKCSndN0IVPS0GAAoLCgkp3cPIXD0tBgAKFgoUUhIKEDIONTcwLjAwMDAwMDAwMDAqSURTTzo6MTIyMDIzZDg0ZWI0MDE5ZWE3NzVmMzY0NTU0YzM1NThjYTc5ZDQyZGUxMjk4ODRhZGNmMWEyNTk4MWNlOGZkZmZhZTU53fF+8TwtBgBCKgomCiQIARIgsKDXx/J5/37sWqsgLM30Alfzt09dqWCFmp3HzTZItL8QHg==', + created_at: '2025-02-03T13:33:53.180125Z', }, - '00bdacaa0cb7c92062e4d8802864e45053b8ab7416d244eaa3fcae9e5d872c0a18ca101220de0fe5f976df9b62050353ac5380b1f3ba0bc40a9dabb5d5501e49ca16560d41': - { - contract: { - template_id: - '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:IssuingMiningRound', - contract_id: - '00bdacaa0cb7c92062e4d8802864e45053b8ab7416d244eaa3fcae9e5d872c0a18ca101220de0fe5f976df9b62050353ac5380b1f3ba0bc40a9dabb5d5501e49ca16560d41', - payload: { - dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', - optIssuancePerValidatorFaucetCoupon: '570.0', - issuancePerFeaturedAppRewardCoupon: '100.0', - opensAt: '2025-02-03T13:54:24.945605Z', - issuancePerSvRewardCoupon: '30.4414003044', - targetClosesAt: '2025-02-03T14:14:24.945605Z', - issuancePerUnfeaturedAppRewardCoupon: '0.6', - round: { - number: '11', - }, - issuancePerValidatorRewardCoupon: '0.2', + domain_id: + 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + }, + '00bdacaa0cb7c92062e4d8802864e45053b8ab7416d244eaa3fcae9e5d872c0a18ca101220de0fe5f976df9b62050353ac5380b1f3ba0bc40a9dabb5d5501e49ca16560d41': + { + contract: { + template_id: + '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:IssuingMiningRound', + contract_id: + '00bdacaa0cb7c92062e4d8802864e45053b8ab7416d244eaa3fcae9e5d872c0a18ca101220de0fe5f976df9b62050353ac5380b1f3ba0bc40a9dabb5d5501e49ca16560d41', + payload: { + dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + optIssuancePerValidatorFaucetCoupon: '570.0', + issuancePerFeaturedAppRewardCoupon: '100.0', + opensAt: '2025-02-03T13:54:24.945605Z', + issuancePerSvRewardCoupon: '30.4414003044', + targetClosesAt: '2025-02-03T14:14:24.945605Z', + issuancePerUnfeaturedAppRewardCoupon: '0.6', + round: { + number: '11', }, - created_event_blob: - 'CgMyLjESmwQKRQC9rKoMt8kgYuTYgChk5FBTuKt0FtJE6qP8rp5dhywKGMoQEiDeD+X5dt+bYgUDU6xTgLHzugvECp2rtdVQHknKFlYNQRINc3BsaWNlLWFtdWxldBplCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGhJJc3N1aW5nTWluaW5nUm91bmQi2wFq2AEKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgWChAKDjIMMC4yMDAwMDAwMDAwChIKEDIOMTAwLjAwMDAwMDAwMDAKEAoOMgwwLjYwMDAwMDAwMDAKEQoPMg0zMC40NDE0MDAzMDQ0CgsKCSnFMeo6PS0GAAoLCgkpxb1wgj0tBgAKFgoUUhIKEDIONTcwLjAwMDAwMDAwMDAqSURTTzo6MTIyMDIzZDg0ZWI0MDE5ZWE3NzVmMzY0NTU0YzM1NThjYTc5ZDQyZGUxMjk4ODRhZGNmMWEyNTk4MWNlOGZkZmZhZTU5xesmFz0tBgBCKgomCiQIARIgCj2GvEkVQONyQjgx1nPbqFpVGinA5bE6t/CfhjQiyV8QHg==', - created_at: '2025-02-03T13:44:24.945605Z', + issuancePerValidatorRewardCoupon: '0.2', }, - domain_id: - 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + created_event_blob: + 'CgMyLjESmwQKRQC9rKoMt8kgYuTYgChk5FBTuKt0FtJE6qP8rp5dhywKGMoQEiDeD+X5dt+bYgUDU6xTgLHzugvECp2rtdVQHknKFlYNQRINc3BsaWNlLWFtdWxldBplCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGhJJc3N1aW5nTWluaW5nUm91bmQi2wFq2AEKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgWChAKDjIMMC4yMDAwMDAwMDAwChIKEDIOMTAwLjAwMDAwMDAwMDAKEAoOMgwwLjYwMDAwMDAwMDAKEQoPMg0zMC40NDE0MDAzMDQ0CgsKCSnFMeo6PS0GAAoLCgkpxb1wgj0tBgAKFgoUUhIKEDIONTcwLjAwMDAwMDAwMDAqSURTTzo6MTIyMDIzZDg0ZWI0MDE5ZWE3NzVmMzY0NTU0YzM1NThjYTc5ZDQyZGUxMjk4ODRhZGNmMWEyNTk4MWNlOGZkZmZhZTU5xesmFz0tBgBCKgomCiQIARIgCj2GvEkVQONyQjgx1nPbqFpVGinA5bE6t/CfhjQiyV8QHg==', + created_at: '2025-02-03T13:44:24.945605Z', }, - '00299522d1821229bd7c34fc327002efe2dccdb0f589b74208bbd92563411a937fca1012203ef49e67a05ca824e7109fbf4fce3a49ce1b6a556fea9c292316509840bb1156': - { - contract: { - template_id: - '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:IssuingMiningRound', - contract_id: - '00299522d1821229bd7c34fc327002efe2dccdb0f589b74208bbd92563411a937fca1012203ef49e67a05ca824e7109fbf4fce3a49ce1b6a556fea9c292316509840bb1156', - payload: { - dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', - optIssuancePerValidatorFaucetCoupon: '570.0', - issuancePerFeaturedAppRewardCoupon: '100.0', - opensAt: '2025-02-03T14:04:54.415965Z', - issuancePerSvRewardCoupon: '30.4414003044', - targetClosesAt: '2025-02-03T14:24:54.415965Z', - issuancePerUnfeaturedAppRewardCoupon: '0.6', - round: { - number: '12', - }, - issuancePerValidatorRewardCoupon: '0.2', + domain_id: + 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + }, + '00299522d1821229bd7c34fc327002efe2dccdb0f589b74208bbd92563411a937fca1012203ef49e67a05ca824e7109fbf4fce3a49ce1b6a556fea9c292316509840bb1156': + { + contract: { + template_id: + '4646d50cbdec6f088c98ae543da5c973d2d1be3363b9f32eb097d8fdc063ade7:Splice.Round:IssuingMiningRound', + contract_id: + '00299522d1821229bd7c34fc327002efe2dccdb0f589b74208bbd92563411a937fca1012203ef49e67a05ca824e7109fbf4fce3a49ce1b6a556fea9c292316509840bb1156', + payload: { + dso: 'DSO::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + optIssuancePerValidatorFaucetCoupon: '570.0', + issuancePerFeaturedAppRewardCoupon: '100.0', + opensAt: '2025-02-03T14:04:54.415965Z', + issuancePerSvRewardCoupon: '30.4414003044', + targetClosesAt: '2025-02-03T14:24:54.415965Z', + issuancePerUnfeaturedAppRewardCoupon: '0.6', + round: { + number: '12', }, - created_event_blob: - 'CgMyLjESmwQKRQAplSLRghIpvXw0/DJwAu/i3M2w9Ym3Qgi72SVjQRqTf8oQEiA+9J5noFyoJOcQn79PzjpJzhtqVW/qnCkjFlCYQLsRVhINc3BsaWNlLWFtdWxldBplCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGhJJc3N1aW5nTWluaW5nUm91bmQi2wFq2AEKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgYChAKDjIMMC4yMDAwMDAwMDAwChIKEDIOMTAwLjAwMDAwMDAwMDAKEAoOMgwwLjYwMDAwMDAwMDAKEQoPMg0zMC40NDE0MDAzMDQ0CgsKCSldJm9gPS0GAAoLCgkpXbL1pz0tBgAKFgoUUhIKEDIONTcwLjAwMDAwMDAwMDAqSURTTzo6MTIyMDIzZDg0ZWI0MDE5ZWE3NzVmMzY0NTU0YzM1NThjYTc5ZDQyZGUxMjk4ODRhZGNmMWEyNTk4MWNlOGZkZmZhZTU5XeCrPD0tBgBCKgomCiQIARIgSQFlf26Y19qiziq/8Wl9fkGKd9VqHSK5u3EMy7rZZf4QHg==', - created_at: '2025-02-03T13:54:54.415965Z', + issuancePerValidatorRewardCoupon: '0.2', }, - domain_id: - 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + created_event_blob: + 'CgMyLjESmwQKRQAplSLRghIpvXw0/DJwAu/i3M2w9Ym3Qgi72SVjQRqTf8oQEiA+9J5noFyoJOcQn79PzjpJzhtqVW/qnCkjFlCYQLsRVhINc3BsaWNlLWFtdWxldBplCkA0NjQ2ZDUwY2JkZWM2ZjA4OGM5OGFlNTQzZGE1Yzk3M2QyZDFiZTMzNjNiOWYzMmViMDk3ZDhmZGMwNjNhZGU3EgZTcGxpY2USBVJvdW5kGhJJc3N1aW5nTWluaW5nUm91bmQi2wFq2AEKTQpLOklEU086OjEyMjAyM2Q4NGViNDAxOWVhNzc1ZjM2NDU1NGMzNTU4Y2E3OWQ0MmRlMTI5ODg0YWRjZjFhMjU5ODFjZThmZGZmYWU1CgoKCGoGCgQKAhgYChAKDjIMMC4yMDAwMDAwMDAwChIKEDIOMTAwLjAwMDAwMDAwMDAKEAoOMgwwLjYwMDAwMDAwMDAKEQoPMg0zMC40NDE0MDAzMDQ0CgsKCSldJm9gPS0GAAoLCgkpXbL1pz0tBgAKFgoUUhIKEDIONTcwLjAwMDAwMDAwMDAqSURTTzo6MTIyMDIzZDg0ZWI0MDE5ZWE3NzVmMzY0NTU0YzM1NThjYTc5ZDQyZGUxMjk4ODRhZGNmMWEyNTk4MWNlOGZkZmZhZTU5XeCrPD0tBgBCKgomCiQIARIgSQFlf26Y19qiziq/8Wl9fkGKd9VqHSK5u3EMy7rZZf4QHg==', + created_at: '2025-02-03T13:54:54.415965Z', }, - }, - }) - ); + domain_id: + 'global-domain::122023d84eb4019ea775f364554c3558ca79d42de129884adcf1a25981ce8fdffae5', + }, + }, + }); }), - rest.post(`${scanUrl}/v0/activities`, (_, res, ctx) => { - return res( - ctx.json({ - activities: [ - { - activity_type: 'transfer', - event_id: '#1220beadd2f791e69719e8ee03a6dd6e3b9c2b9196b8b679a190d203fc2c8a6a4bff:5', - offset: '00000000000000002f', - date: new Date(), - domain_id: - 'global-domain::1220af85fa0c58e7f551de289be22793993ce7672cb0751afa2f2de397ce4a695677', - round: 1, - transfer: { - sender: { + http.post(`${scanUrl}/v0/activities`, () => { + return HttpResponse.json({ + activities: [ + { + activity_type: 'transfer', + event_id: '#1220beadd2f791e69719e8ee03a6dd6e3b9c2b9196b8b679a190d203fc2c8a6a4bff:5', + offset: '00000000000000002f', + date: new Date(), + domain_id: + 'global-domain::1220af85fa0c58e7f551de289be22793993ce7672cb0751afa2f2de397ce4a695677', + round: 1, + transfer: { + sender: { + party: + 'charlie__wallet__user::12200d3c885d2cb51226911f828da25f7f0fc0d06b8c6bf00c714266729033f138f7', + input_amulet_amount: '5.0000000000', + input_app_reward_amount: '0.0000000000', + input_validator_reward_amount: '0.0000000000', + input_sv_reward_amount: '0.0000000000', + sender_change_fee: '0.0300000000', + sender_change_amount: '3.8950000000', + sender_fee: '0.0000000000', + holding_fees: '0.0000000000', + }, + balance_changes: [ + { party: 'charlie__wallet__user::12200d3c885d2cb51226911f828da25f7f0fc0d06b8c6bf00c714266729033f138f7', - input_amulet_amount: '5.0000000000', - input_app_reward_amount: '0.0000000000', - input_validator_reward_amount: '0.0000000000', - input_sv_reward_amount: '0.0000000000', - sender_change_fee: '0.0300000000', - sender_change_amount: '3.8950000000', - sender_fee: '0.0000000000', - holding_fees: '0.0000000000', + change_to_holding_fees_rate: '0.0000000000', + change_to_initial_amount_as_of_round_zero: '1.1050000000', }, - balance_changes: [ - { - party: - 'charlie__wallet__user::12200d3c885d2cb51226911f828da25f7f0fc0d06b8c6bf00c714266729033f138f7', - change_to_holding_fees_rate: '0.0000000000', - change_to_initial_amount_as_of_round_zero: '1.1050000000', - }, - ], - receivers: [], - }, + ], + receivers: [], }, - ], - }) - ); + }, + ], + }); }), - rest.get(`${scanUrl}/v0/round-of-latest-data`, (_, res, ctx) => { - return res(ctx.json({ round: 1, effectiveAt: new Date() })); + http.get(`${scanUrl}/v0/round-of-latest-data`, () => { + return HttpResponse.json({ round: 1, effectiveAt: new Date() }); }), - rest.get(`${scanUrl}/v0/rewards-collected`, (_, res, ctx) => { - return res(ctx.json({ amount: '0.0' })); + http.get(`${scanUrl}/v0/rewards-collected`, () => { + return HttpResponse.json({ amount: '0.0' }); }), - rest.post(`${scanUrl}/v0/amulet-rules`, (_, res, ctx) => { - return res(ctx.json(getAmuletRulesResponse(true))); + http.post(`${scanUrl}/v0/amulet-rules`, () => { + return HttpResponse.json(getAmuletRulesResponse(true)); }), - rest.get( + http.get<{ partyId: string }, null, LookupEntryByPartyResponse | ErrorResponse>( `${scanUrl}/v0/ans-entries/by-party/:partyId`, - (req, res, ctx) => { + ({ params }) => { if ( - req.params['partyId'] === + params['partyId'] === 'charlie__wallet__user::12200d3c885d2cb51226911f828da25f7f0fc0d06b8c6bf00c714266729033f138f7' ) { - return res( - ctx.json({ - entry: { - contract_id: - '00a0e1386b02ea75f0ddcfc7c4fbfb8eba09cd3c3748b160de1f17450bb99faaa7ca0212209680fb7e9526ddccf5931db169bf8ba16e4e60d7e23a74c28e9492e8b62d1194', - user: 'google-oauth2_007c106265882859845879513::122033667ff9ec083bf5a6b512655bd7986dfc4d6644978c944129a0f46489bc41d4', - name: `charlie.unverified.${amuletNameServiceAcronym.toLowerCase()}`, - url: '', - description: '', - expires_at: new Date('2024-01-04T07:37:05.004139Z'), - }, - }) - ); + return HttpResponse.json({ + entry: { + contract_id: + '00a0e1386b02ea75f0ddcfc7c4fbfb8eba09cd3c3748b160de1f17450bb99faaa7ca0212209680fb7e9526ddccf5931db169bf8ba16e4e60d7e23a74c28e9492e8b62d1194', + user: 'google-oauth2_007c106265882859845879513::122033667ff9ec083bf5a6b512655bd7986dfc4d6644978c944129a0f46489bc41d4', + name: `charlie.unverified.${amuletNameServiceAcronym.toLowerCase()}`, + url: '', + description: '', + expires_at: new Date('2024-01-04T07:37:05.004139Z'), + }, + }); } else { - return res( - ctx.status(404), - ctx.json({ + return HttpResponse.json( + { error: 'No ans entry found for party: alice::122015ba7aa9054dbad217110e8fbf5dd550a59fb56df5986913f7b9a8e63bad8570', - }) + }, + { status: 404 } ); } } ), validatorLicensesHandler(scanUrl), - rest.all('*', req => { - console.error(JSON.stringify(req)); + http.all('*', ({ request }) => { + console.error(`unhandled ${request.method} ${request.url}`); }), ]; }; diff --git a/apps/scan/frontend/src/__tests__/scan.test.tsx b/apps/scan/frontend/src/__tests__/scan.test.tsx index bdd2fdea0f..4e148d9e30 100644 --- a/apps/scan/frontend/src/__tests__/scan.test.tsx +++ b/apps/scan/frontend/src/__tests__/scan.test.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { GetAmuletRulesResponse, GetBackfillingStatusResponse, @@ -54,12 +54,10 @@ test('total circulating amulet balance is displayed', async () => { test('backfilling indicator shows when backfilling', async () => { server.use( - rest.get(`${scanUrl}/v0/backfilling/status`, (_, res, ctx) => { - return res( - ctx.json({ - complete: false, - }) - ); + http.get(`${scanUrl}/v0/backfilling/status`, () => { + return HttpResponse.json({ + complete: false, + }); }) ); render(); @@ -69,12 +67,10 @@ test('backfilling indicator shows when backfilling', async () => { test('backfilling indicator does not shows when not backfilling', async () => { server.use( - rest.get(`${scanUrl}/v0/backfilling/status`, (_, res, ctx) => { - return res( - ctx.json({ - complete: true, - }) - ); + http.get(`${scanUrl}/v0/backfilling/status`, () => { + return HttpResponse.json({ + complete: true, + }); }) ); render(); @@ -84,8 +80,8 @@ test('backfilling indicator does not shows when not backfilling', async () => { test('backfilling indicator does not shows when response is unclear', async () => { server.use( - rest.get(`${scanUrl}/v0/backfilling/status`, (_, res, ctx) => { - return res(ctx.status(503, 'Internal Server Error')); + http.get(`${scanUrl}/v0/backfilling/status`, () => { + return new HttpResponse(null, { status: 503, statusText: 'Internal Server Error' }); }) ); render(); @@ -119,8 +115,8 @@ test('Fees with value 0 are not shown', async () => { test('Fees with value greater than 0 are shown', async () => { const amuletConfig = amuletRules(false).configSchedule.initialValue; server.use( - rest.post(`${scanUrl}/v0/amulet-rules`, (_, res, ctx) => { - return res(ctx.json(getAmuletRulesResponse(false))); + http.post(`${scanUrl}/v0/amulet-rules`, () => { + return HttpResponse.json(getAmuletRulesResponse(false)); }) ); const user = userEvent.setup(); diff --git a/apps/scan/frontend/src/__tests__/setup/setup.ts b/apps/scan/frontend/src/__tests__/setup/setup.ts index dbe46d320c..85fee8ee58 100644 --- a/apps/scan/frontend/src/__tests__/setup/setup.ts +++ b/apps/scan/frontend/src/__tests__/setup/setup.ts @@ -1,5 +1,16 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 + +// happy-dom@20 doesn't lowercase header names during iteration as the Fetch +// spec requires; the openapi clients read `headers["content-type"]`, so without +// this patch they fail to parse JSON responses from MSW. +const _origForEach = Headers.prototype.forEach; +Headers.prototype.forEach = function (cb, thisArg) { + return _origForEach.call(this, function (value: string, name: string, parent: Headers) { + cb.call(thisArg, value, name.toLowerCase(), parent); + }); +}; + import { cleanup } from '@testing-library/react'; import crypto from 'crypto'; import { SetupServer } from 'msw/node'; diff --git a/apps/splitwell/frontend/package.json b/apps/splitwell/frontend/package.json index c90a64a57c..638d4f1b71 100644 --- a/apps/splitwell/frontend/package.json +++ b/apps/splitwell/frontend/package.json @@ -21,12 +21,16 @@ "@mui/icons-material": "^7.3.4", "@mui/material": "^7.3.4", "@tanstack/react-query": "5.90.20", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", "react": "18.3.1", "react-dom": "18.3.1", "react-helmet-async": "^2.0.5", "react-router": "^7.12.0", - "uuid": "9.0.0", - "web-vitals": "4.2.4" + "uuid": "^14.0.0", + "web-vitals": "4.2.4", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -43,12 +47,12 @@ "@types/react-dom": "18.3.6", "@types/uuid": "8.3.4", "@vitejs/plugin-react": "^6.0.1", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", "happy-dom": "^20.0.11", - "msw": "^1.2.5", + "msw": "^2.14.2", "prettier": "3.5.3", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", diff --git a/apps/splitwell/frontend/src/__tests__/mocks/handlers/json-api.ts b/apps/splitwell/frontend/src/__tests__/mocks/handlers/json-api.ts index 8ab81f5aa3..d212e361ad 100644 --- a/apps/splitwell/frontend/src/__tests__/mocks/handlers/json-api.ts +++ b/apps/splitwell/frontend/src/__tests__/mocks/handlers/json-api.ts @@ -1,6 +1,6 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { RestHandler, rest } from 'msw'; +import { http, HttpHandler, HttpResponse } from 'msw'; import { alicePartyId } from '../constants'; @@ -11,17 +11,15 @@ export const domainDisconnectErrorResponse = { ], }; -export const buildJsonApiMock = (jsonApiUrl: string): RestHandler[] => [ - rest.get(`${jsonApiUrl}v2/users/:userid`, (_, res, ctx) => { - return res( - ctx.json({ - user: { - primaryParty: alicePartyId, - userId: 'alice', - }, - status: 200, - }) - ); +export const buildJsonApiMock = (jsonApiUrl: string): HttpHandler[] => [ + http.get(`${jsonApiUrl}v2/users/:userid`, () => { + return HttpResponse.json({ + user: { + primaryParty: alicePartyId, + userId: 'alice', + }, + status: 200, + }); }), ]; diff --git a/apps/splitwell/frontend/src/__tests__/mocks/handlers/scan-api.ts b/apps/splitwell/frontend/src/__tests__/mocks/handlers/scan-api.ts index 3e16f29fcb..d045be4082 100644 --- a/apps/splitwell/frontend/src/__tests__/mocks/handlers/scan-api.ts +++ b/apps/splitwell/frontend/src/__tests__/mocks/handlers/scan-api.ts @@ -1,6 +1,6 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { RestHandler, rest } from 'msw'; +import { http, HttpHandler, HttpResponse } from 'msw'; import { ErrorResponse, LookupEntryByNameResponse, @@ -11,76 +11,65 @@ import { import { alicePartyId, bobPartyId } from '../constants'; -export const buildScanMock = (scanUrl: string): RestHandler[] => [ - rest.get(`${scanUrl}/v0/dso-party-id`, (_, res, ctx) => { - return res( - ctx.json({ - dso_party_id: 'DSO::1220809612f787469c92b924ad1d32f1cbc0bdbd4eeda55a50469250bcf64b8becf2', - }) - ); +export const buildScanMock = (scanUrl: string): HttpHandler[] => [ + http.get(`${scanUrl}/v0/dso-party-id`, () => { + return HttpResponse.json({ + dso_party_id: 'DSO::1220809612f787469c92b924ad1d32f1cbc0bdbd4eeda55a50469250bcf64b8becf2', + }); }), - rest.get( + http.get<{ partyId: string }, null, LookupEntryByPartyResponse | ErrorResponse>( `${scanUrl}/v0/ans-entries/by-party/:partyId`, - (req, res, ctx) => { - if (req.params.partyId === alicePartyId) { - return res( - ctx.json({ - entry: { - contract_id: - '00c8e178f8b0b2c2955103b3fa59ccdc5f34861c4bcf659844c2959ba9febf3f61ca0212207e6c7b0db1b456c2f3f23c3b0c75b02dfc0c470cd1ea3fb603a01527e414c922', - name: 'alice.unverified.tns', - url: 'https://alice-url.tns.com', - description: '', - expires_at: new Date('2024-01-07T14:50:26.364476Z'), - user: alicePartyId, - }, - }) - ); + ({ params }) => { + if (params.partyId === alicePartyId) { + return HttpResponse.json({ + entry: { + contract_id: + '00c8e178f8b0b2c2955103b3fa59ccdc5f34861c4bcf659844c2959ba9febf3f61ca0212207e6c7b0db1b456c2f3f23c3b0c75b02dfc0c470cd1ea3fb603a01527e414c922', + name: 'alice.unverified.tns', + url: 'https://alice-url.tns.com', + description: '', + expires_at: new Date('2024-01-07T14:50:26.364476Z'), + user: alicePartyId, + }, + }); } - if (req.params.partyId === bobPartyId) { - return res( - ctx.json({ - entry: { - contract_id: - '00c8e178f8b0b2c2955103b3fa59ccdc5f34861c4bcf659844c2959ba9febf3f61ca0212207e6c7b0db1b456c2f3f23c3b0c75b02dfc0c470cd1ea3fb603a01527e414c922', - name: 'bob.unverified.tns', - url: 'https://bob-url.tns.com', - description: '', - expires_at: new Date('2024-01-07T14:50:26.364476Z'), - user: bobPartyId, - }, - }) - ); + if (params.partyId === bobPartyId) { + return HttpResponse.json({ + entry: { + contract_id: + '00c8e178f8b0b2c2955103b3fa59ccdc5f34861c4bcf659844c2959ba9febf3f61ca0212207e6c7b0db1b456c2f3f23c3b0c75b02dfc0c470cd1ea3fb603a01527e414c922', + name: 'bob.unverified.tns', + url: 'https://bob-url.tns.com', + description: '', + expires_at: new Date('2024-01-07T14:50:26.364476Z'), + user: bobPartyId, + }, + }); } - return res( - ctx.status(404), - ctx.json({ + return HttpResponse.json( + { error: `No tns entry found for party: ${alicePartyId}`, - }) + }, + { status: 404 } ); } ), - rest.get( + http.get<{ name: string }, null, LookupEntryByNameResponse | ErrorResponse>( `${scanUrl}/v0/ans-entries/by-name`, - (_, res, ctx) => { - return res( - ctx.status(404), - ctx.json({ + () => { + return HttpResponse.json( + { error: `No ans entry found for party: ${alicePartyId}`, - }) - ); - } - ), - rest.get( - `${scanUrl}/v0/ans-entries`, - (_, res, ctx) => { - return res( - ctx.json({ - entries: [], - }) + }, + { status: 404 } ); } ), + http.get<{ partyId: string }, null, ListEntriesResponse>(`${scanUrl}/v0/ans-entries`, () => { + return HttpResponse.json({ + entries: [], + }); + }), ]; diff --git a/apps/splitwell/frontend/src/__tests__/mocks/handlers/splitwell-api.ts b/apps/splitwell/frontend/src/__tests__/mocks/handlers/splitwell-api.ts index b6456fb154..66b6c6cc4e 100644 --- a/apps/splitwell/frontend/src/__tests__/mocks/handlers/splitwell-api.ts +++ b/apps/splitwell/frontend/src/__tests__/mocks/handlers/splitwell-api.ts @@ -1,6 +1,6 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { RestHandler, rest } from 'msw'; +import { http, HttpHandler, HttpResponse } from 'msw'; import { GetConnectedDomainsResponse, GetProviderPartyIdResponse, @@ -24,112 +24,98 @@ import { splitwellProviderPartyId, } from '../constants'; -export const buildSplitwellMock = (splitwellUrl: string): RestHandler[] => [ - rest.get(`${splitwellUrl}/provider-party-id`, (_, res, ctx) => { - return res( - ctx.json({ - provider_party_id: splitwellProviderPartyId, - }) - ); +export const buildSplitwellMock = (splitwellUrl: string): HttpHandler[] => [ + http.get(`${splitwellUrl}/provider-party-id`, () => { + return HttpResponse.json({ + provider_party_id: splitwellProviderPartyId, + }); }), - rest.get(`${splitwellUrl}/splitwell-installs`, (_, res, ctx) => { - return res( - ctx.json({ - installs: [ - { - contract_id: splitwellInstallCid, - domain_id: splitwellDomainId, - }, - ], - }) - ); + http.get(`${splitwellUrl}/splitwell-installs`, () => { + return HttpResponse.json({ + installs: [ + { + contract_id: splitwellInstallCid, + domain_id: splitwellDomainId, + }, + ], + }); }), - rest.get(`${splitwellUrl}/splitwell-rules`, (_, res, ctx) => { - return res( - ctx.json({ - rules: [ - { - contract: { - template_id: - 'cbca8a4f8d6170f38cd7a5c9cc0371cc3ccb4fb5bf5daf0702aa2c3849ac6bde:Splice.Splitwell:SplitwellRules', - contract_id: - '00f2402e664650fdb4f40e42f79facd0e007c344743c67b69da3705a2c171dbb26ca021220345fc60e560266dbba9f2544d07b0292539275995020153ccca14c5076df9a55', - payload: SplitwellRules.encode({ - provider: splitwellProviderPartyId, - }), - created_event_blob: '', - created_at: '2023-10-05T15:35:40.054390Z', - }, - domain_id: splitwellDomainId, + http.get(`${splitwellUrl}/splitwell-rules`, () => { + return HttpResponse.json({ + rules: [ + { + contract: { + template_id: + 'cbca8a4f8d6170f38cd7a5c9cc0371cc3ccb4fb5bf5daf0702aa2c3849ac6bde:Splice.Splitwell:SplitwellRules', + contract_id: + '00f2402e664650fdb4f40e42f79facd0e007c344743c67b69da3705a2c171dbb26ca021220345fc60e560266dbba9f2544d07b0292539275995020153ccca14c5076df9a55', + payload: SplitwellRules.encode({ + provider: splitwellProviderPartyId, + }), + created_event_blob: '', + created_at: '2023-10-05T15:35:40.054390Z', }, - ], - }) - ); + domain_id: splitwellDomainId, + }, + ], + }); }), - rest.get(`${splitwellUrl}/connected-domains`, (_, res, ctx) => { - return res( - ctx.json({ - domain_ids: [ - 'global-domain::1220809612f787469c92b924ad1d32f1cbc0bdbd4eeda55a50469250bcf64b8becf2', - splitwellDomainId, - ], - }) - ); + http.get(`${splitwellUrl}/connected-domains`, () => { + return HttpResponse.json({ + domain_ids: [ + 'global-domain::1220809612f787469c92b924ad1d32f1cbc0bdbd4eeda55a50469250bcf64b8becf2', + splitwellDomainId, + ], + }); }), - rest.get(`${splitwellUrl}/splitwell-domains`, (_, res, ctx) => { - return res( - ctx.json({ - preferred: splitwellDomainId, - other_domain_ids: [], - }) - ); + http.get(`${splitwellUrl}/splitwell-domains`, () => { + return HttpResponse.json({ + preferred: splitwellDomainId, + other_domain_ids: [], + }); }), - rest.get(`${splitwellUrl}/group-invites`, (_, res, ctx) => { - return res( - ctx.json({ - group_invites: [], - }) - ); + http.get(`${splitwellUrl}/group-invites`, () => { + return HttpResponse.json({ + group_invites: [], + }); }), - rest.get(`${splitwellUrl}/groups`, (_, res, ctx) => { - return res( - ctx.json({ - groups: [ - { - contract: { - template_id: - 'cbca8a4f8d6170f38cd7a5c9cc0371cc3ccb4fb5bf5daf0702aa2c3849ac6bde:Splice.Splitwell:Group', - contract_id: - '00857d7d5500196ffed47bc83b2d709a5b841c8724a6c03c9024ed3fb16054a5b0ca0212204f5987937925504ea6ea64c731b6637fc9d184760c1266eab55b02c9399d23f8', - payload: Group.encode({ - provider: splitwellProviderPartyId, - id: { - unpack: groupName, - }, - owner: alicePartyId, - members: [], - dso: 'DSO::122065980b045703ed871be9b93afb28b61c874b667434259d1df090096837e3ffd0', - acceptDuration: { - microseconds: '300000000', - }, - }), - created_event_blob: '', - created_at: '2023-10-06T09:20:54.077318Z', - }, - domain_id: splitwellDomainId, + http.get(`${splitwellUrl}/groups`, () => { + return HttpResponse.json({ + groups: [ + { + contract: { + template_id: + 'cbca8a4f8d6170f38cd7a5c9cc0371cc3ccb4fb5bf5daf0702aa2c3849ac6bde:Splice.Splitwell:Group', + contract_id: + '00857d7d5500196ffed47bc83b2d709a5b841c8724a6c03c9024ed3fb16054a5b0ca0212204f5987937925504ea6ea64c731b6637fc9d184760c1266eab55b02c9399d23f8', + payload: Group.encode({ + provider: splitwellProviderPartyId, + id: { + unpack: groupName, + }, + owner: alicePartyId, + members: [], + dso: 'DSO::122065980b045703ed871be9b93afb28b61c874b667434259d1df090096837e3ffd0', + acceptDuration: { + microseconds: '300000000', + }, + }), + created_event_blob: '', + created_at: '2023-10-06T09:20:54.077318Z', }, - ], - }) - ); + domain_id: splitwellDomainId, + }, + ], + }); }), - rest.get(`${splitwellUrl}/balances`, (_, res, ctx) => { - return res(ctx.json({ balances: {} })); + http.get(`${splitwellUrl}/balances`, () => { + return HttpResponse.json({ balances: {} }); }), - rest.get(`${splitwellUrl}/balance-updates`, (_, res, ctx) => { - return res(ctx.json({ balance_updates: [] })); + http.get(`${splitwellUrl}/balance-updates`, () => { + return HttpResponse.json({ balance_updates: [] }); }), - rest.get(`${splitwellUrl}/accepted-group-invites`, (_, res, ctx) => { - return res(ctx.json({ accepted_group_invites: [] })); + http.get(`${splitwellUrl}/accepted-group-invites`, () => { + return HttpResponse.json({ accepted_group_invites: [] }); }), ]; diff --git a/apps/splitwell/frontend/src/__tests__/setup/setup.ts b/apps/splitwell/frontend/src/__tests__/setup/setup.ts index 55dd91ea06..f70e45472b 100644 --- a/apps/splitwell/frontend/src/__tests__/setup/setup.ts +++ b/apps/splitwell/frontend/src/__tests__/setup/setup.ts @@ -1,5 +1,16 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 + +// happy-dom@20 doesn't lowercase header names during iteration as the Fetch +// spec requires; the openapi clients read `headers["content-type"]`, so without +// this patch they fail to parse JSON responses from MSW. +const _origForEach = Headers.prototype.forEach; +Headers.prototype.forEach = function (cb, thisArg) { + return _origForEach.call(this, function (value: string, name: string, parent: Headers) { + cb.call(thisArg, value, name.toLowerCase(), parent); + }); +}; + import { cleanup } from '@testing-library/react'; import crypto from 'crypto'; import { SetupServer } from 'msw/node'; diff --git a/apps/splitwell/frontend/src/__tests__/splitwell.test.tsx b/apps/splitwell/frontend/src/__tests__/splitwell.test.tsx index 12a754bb4b..6731a89d78 100644 --- a/apps/splitwell/frontend/src/__tests__/splitwell.test.tsx +++ b/apps/splitwell/frontend/src/__tests__/splitwell.test.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { ListAcceptedGroupInvitesResponse, ListBalanceUpdatesResponse, @@ -83,26 +83,28 @@ describe('alice can', () => { server.resetHandlers(); server.use( // simulating 2 failures here. react-query will retry these - rest.post(exerciseEndpoint, (_, res, ctx) => { - return res.once(ctx.status(400), ctx.json(domainDisconnectErrorResponse)); + http.post( + exerciseEndpoint, + () => HttpResponse.json(domainDisconnectErrorResponse, { status: 400 }), + { once: true } + ), + http.post( + exerciseEndpoint, + () => HttpResponse.json(domainDisconnectErrorResponse, { status: 400 }), + { once: true } + ), + http.post(exerciseEndpoint, () => { + return HttpResponse.json(exerciseCreateInviteResponse); }), - rest.post(exerciseEndpoint, (_, res, ctx) => { - return res.once(ctx.status(400), ctx.json(domainDisconnectErrorResponse)); - }), - rest.post(exerciseEndpoint, (_, res, ctx) => { - return res(ctx.json(exerciseCreateInviteResponse)); - }), - rest.get(`${window.splice_config.services.splitwell.url}/group-invites`, (_, res, ctx) => { - return res( - ctx.json({ - group_invites: [ - { - contract: fakeGroupInvite, - domain_id: splitwellDomainId, - }, - ], - }) - ); + http.get(`${window.splice_config.services.splitwell.url}/group-invites`, () => { + return HttpResponse.json({ + group_invites: [ + { + contract: fakeGroupInvite, + domain_id: splitwellDomainId, + }, + ], + }); }) ); @@ -118,23 +120,13 @@ describe('alice can', () => { render(); server.use( - rest.get( - `${window.splice_config.services.splitwell.url}/accepted-group-invites`, - (_, res, ctx) => { - return res( - ctx.json({ - accepted_group_invites: [ - makeAcceptedGroupInvite( - splitwellProviderPartyId, - alicePartyId, - bobPartyId, - groupName - ), - ], - }) - ); - } - ) + http.get(`${window.splice_config.services.splitwell.url}/accepted-group-invites`, () => { + return HttpResponse.json({ + accepted_group_invites: [ + makeAcceptedGroupInvite(splitwellProviderPartyId, alicePartyId, bobPartyId, groupName), + ], + }); + }) ); await expect(screen.findByRole('button', { name: 'Add' })).resolves.toBeDefined(); @@ -144,55 +136,53 @@ describe('alice can', () => { render(); server.use( - rest.get(`${window.splice_config.services.splitwell.url}/balance-updates`, (_, res, ctx) => { - return res( - ctx.json({ - balance_updates: [ - makeBalanceUpdate( - splitwellProviderPartyId, - alicePartyId, - groupName, - { - tag: 'ExternalPayment', - value: { - payer: alicePartyId, - description: 'expenses', - amount: '30.0', - }, + http.get(`${window.splice_config.services.splitwell.url}/balance-updates`, () => { + return HttpResponse.json({ + balance_updates: [ + makeBalanceUpdate( + splitwellProviderPartyId, + alicePartyId, + groupName, + { + tag: 'ExternalPayment', + value: { + payer: alicePartyId, + description: 'expenses', + amount: '30.0', }, - 'cid3' - ), - makeBalanceUpdate( - splitwellProviderPartyId, - alicePartyId, - groupName, - { - tag: 'Transfer', - value: { - sender: bobPartyId, - receiver: alicePartyId, - amount: '40.0', - }, + }, + 'cid3' + ), + makeBalanceUpdate( + splitwellProviderPartyId, + alicePartyId, + groupName, + { + tag: 'Transfer', + value: { + sender: bobPartyId, + receiver: alicePartyId, + amount: '40.0', }, - 'cid2' - ), - makeBalanceUpdate( - splitwellProviderPartyId, - alicePartyId, - groupName, - { - tag: 'ExternalPayment', - value: { - payer: alicePartyId, - description: 'dinner', - amount: '15.0', - }, + }, + 'cid2' + ), + makeBalanceUpdate( + splitwellProviderPartyId, + alicePartyId, + groupName, + { + tag: 'ExternalPayment', + value: { + payer: alicePartyId, + description: 'dinner', + amount: '15.0', }, - 'cid1' - ), - ], - }) - ); + }, + 'cid1' + ), + ], + }); }) ); diff --git a/apps/sv/frontend/package.json b/apps/sv/frontend/package.json index ca08e83bea..b0be9853e3 100644 --- a/apps/sv/frontend/package.json +++ b/apps/sv/frontend/package.json @@ -24,6 +24,9 @@ "@mui/x-date-pickers": "^8.14.1", "@tanstack/react-form": "^1.23.0", "dayjs": "^1.11.9", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", "oidc-client-ts": "2.2.1", "react": "18.3.1", "react-dom": "18.3.1", @@ -32,8 +35,9 @@ "react-json-pretty": "2.2.0", "react-oidc-context": "2.2.2", "sonner": "^2.0.7", - "uuid": "9.0.0", - "web-vitals": "4.2.4" + "uuid": "^14.0.0", + "web-vitals": "4.2.4", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -51,13 +55,13 @@ "@types/uuid": "8.3.4", "@vitejs/plugin-react": "^6.0.1", "@vitest/ui": "^3.1.2", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", "happy-dom": "^20.0.11", "html-format": "^1.1.7", - "msw": "^1.2.5", + "msw": "^2.14.2", "prettier": "3.5.3", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", diff --git a/apps/sv/frontend/src/__tests__/governance/forms/create-unallocated-unclaimed-activity-form.test.tsx b/apps/sv/frontend/src/__tests__/governance/forms/create-unallocated-unclaimed-activity-form.test.tsx index af28568a0d..faf4ca0e66 100644 --- a/apps/sv/frontend/src/__tests__/governance/forms/create-unallocated-unclaimed-activity-form.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/forms/create-unallocated-unclaimed-activity-form.test.tsx @@ -5,7 +5,7 @@ import { dateTimeFormatISO } from '@lfdecentralizedtrust/splice-common-frontend- import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import dayjs from 'dayjs'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { describe, expect, test } from 'vitest'; import App from '../../../App'; import { CreateUnallocatedUnclaimedActivityRecordForm } from '../../../components/forms/CreateUnallocatedUnclaimedActivityRecordForm'; @@ -340,8 +340,8 @@ describe('Create Unallocated Unclaimed Activity Record Form', () => { test('should show error on form if submission fails', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.status(503), ctx.json({ error: 'Service Unavailable' })); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({ error: 'Service Unavailable' }, { status: 503 }); }) ); @@ -393,8 +393,8 @@ describe('Create Unallocated Unclaimed Activity Record Form', () => { test('should redirect to governance page after successful submission', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.json({})); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({}); }) ); diff --git a/apps/sv/frontend/src/__tests__/governance/forms/grant-revoke-featured-app-form.test.tsx b/apps/sv/frontend/src/__tests__/governance/forms/grant-revoke-featured-app-form.test.tsx index 1338b20f84..b253755c46 100644 --- a/apps/sv/frontend/src/__tests__/governance/forms/grant-revoke-featured-app-form.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/forms/grant-revoke-featured-app-form.test.tsx @@ -12,7 +12,7 @@ import { dateTimeFormatISO } from '@lfdecentralizedtrust/splice-common-frontend- import dayjs from 'dayjs'; import { GrantRevokeFeaturedAppForm } from '../../../components/forms/GrantRevokeFeaturedAppForm'; import { server, svUrl } from '../../setup/setup'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { PROPOSAL_SUMMARY_SUBTITLE, PROPOSAL_SUMMARY_TITLE } from '../../../utils/constants'; describe('SV user can', () => { @@ -394,8 +394,8 @@ describe('Revoke Featured App Form', () => { test('should show error on form if submission fails', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.status(503), ctx.json({ error: 'Service Unavailable' })); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({ error: 'Service Unavailable' }, { status: 503 }); }) ); @@ -427,8 +427,8 @@ describe('Revoke Featured App Form', () => { test('should redirect to governance page after successful submission', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.json({})); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({}); }) ); diff --git a/apps/sv/frontend/src/__tests__/governance/forms/offboard-sv-form.test.tsx b/apps/sv/frontend/src/__tests__/governance/forms/offboard-sv-form.test.tsx index a809401484..712a0a5f01 100644 --- a/apps/sv/frontend/src/__tests__/governance/forms/offboard-sv-form.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/forms/offboard-sv-form.test.tsx @@ -12,7 +12,7 @@ import { dateTimeFormatISO } from '@lfdecentralizedtrust/splice-common-frontend- import dayjs from 'dayjs'; import { OffboardSvForm } from '../../../components/forms/OffboardSvForm'; import { server, svUrl } from '../../setup/setup'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { PROPOSAL_SUMMARY_SUBTITLE, PROPOSAL_SUMMARY_TITLE } from '../../../utils/constants'; describe('SV user can', () => { @@ -241,8 +241,8 @@ describe('Offboard SV Form', () => { test('should show error on form if submission fails', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.status(503), ctx.json({ error: 'Service Unavailable' })); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({ error: 'Service Unavailable' }, { status: 503 }); }) ); @@ -288,8 +288,8 @@ describe('Offboard SV Form', () => { test('should redirect to governance page after successful submission', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.json({})); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({}); }) ); diff --git a/apps/sv/frontend/src/__tests__/governance/forms/pending-fields.test.tsx b/apps/sv/frontend/src/__tests__/governance/forms/pending-fields.test.tsx index 6d785145ea..2c99cb73c8 100644 --- a/apps/sv/frontend/src/__tests__/governance/forms/pending-fields.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/forms/pending-fields.test.tsx @@ -5,7 +5,7 @@ import { getDsoSetConfigAction } from '@lfdecentralizedtrust/splice-common-test- import type { ListDsoRulesVoteRequestsResponse } from '@lfdecentralizedtrust/sv-openapi'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { describe, expect, test } from 'vitest'; import App from '../../../App'; import { SetDsoConfigRulesForm } from '../../../components/forms/SetDsoConfigRulesForm'; @@ -85,8 +85,8 @@ describe('DSO Pending Fields', () => { describe('Pending Fields', () => { test('DSO Pending fields should be disabled and pending info displayed', async () => { server.use( - rest.get(`${svUrl}/v0/admin/sv/voterequests`, (_, res, ctx) => { - return res(ctx.json(proposals)); + http.get(`${svUrl}/v0/admin/sv/voterequests`, () => { + return HttpResponse.json(proposals); }) ); diff --git a/apps/sv/frontend/src/__tests__/governance/forms/set-amulet-rules-form.test.tsx b/apps/sv/frontend/src/__tests__/governance/forms/set-amulet-rules-form.test.tsx index c578b4265d..7dfbbba3f5 100644 --- a/apps/sv/frontend/src/__tests__/governance/forms/set-amulet-rules-form.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/forms/set-amulet-rules-form.test.tsx @@ -4,7 +4,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { describe, expect, test } from 'vitest'; import userEvent from '@testing-library/user-event'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { SvConfigProvider } from '../../../utils'; import App from '../../../App'; import { svPartyId } from '../../mocks/constants'; @@ -279,8 +279,8 @@ describe('Set Amulet Config Rules Form', () => { test('should show error on form if submission fails', { timeout: 10000 }, async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.status(503), ctx.json({ error: 'Service Unavailable' })); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({ error: 'Service Unavailable' }, { status: 503 }); }) ); @@ -319,8 +319,8 @@ describe('Set Amulet Config Rules Form', () => { test('should redirect to governance page after successful submission', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.json({})); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({}); }) ); diff --git a/apps/sv/frontend/src/__tests__/governance/forms/set-dso-rules-form.test.tsx b/apps/sv/frontend/src/__tests__/governance/forms/set-dso-rules-form.test.tsx index 1b0a9c1e9b..126f0a1548 100644 --- a/apps/sv/frontend/src/__tests__/governance/forms/set-dso-rules-form.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/forms/set-dso-rules-form.test.tsx @@ -8,7 +8,7 @@ import { import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import dayjs from 'dayjs'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { describe, expect, test } from 'vitest'; import App from '../../../App'; import { SetDsoConfigRulesForm } from '../../../components/forms/SetDsoConfigRulesForm'; @@ -266,8 +266,8 @@ describe('Set DSO Config Rules Form', () => { test('should show error on form if submission fails', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.status(503), ctx.json({ error: 'Service Unavailable' })); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({ error: 'Service Unavailable' }, { status: 503 }); }) ); @@ -311,8 +311,8 @@ describe('Set DSO Config Rules Form', () => { test('should redirect to governance page after successful submission', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.json({})); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({}); }) ); diff --git a/apps/sv/frontend/src/__tests__/governance/forms/update-sv-reward-weight-form-test.test.tsx b/apps/sv/frontend/src/__tests__/governance/forms/update-sv-reward-weight-form-test.test.tsx index 480a979489..4cd05d9242 100644 --- a/apps/sv/frontend/src/__tests__/governance/forms/update-sv-reward-weight-form-test.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/forms/update-sv-reward-weight-form-test.test.tsx @@ -12,7 +12,7 @@ import { Wrapper } from '../../helpers'; import { dateTimeFormatISO } from '@lfdecentralizedtrust/splice-common-frontend-utils'; import dayjs from 'dayjs'; import { server, svUrl } from '../../setup/setup'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { PROPOSAL_SUMMARY_SUBTITLE } from '../../../utils/constants'; describe('SV user can', () => { @@ -304,8 +304,8 @@ describe('Update SV Reward Weight Form', () => { test('should show error on form if submission fails', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.status(503), ctx.json({ error: 'Service Unavailable' })); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({ error: 'Service Unavailable' }, { status: 503 }); }) ); @@ -408,8 +408,8 @@ describe('Update SV Reward Weight Form', () => { test('should redirect to governance page after successful submission', async () => { server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.json({})); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({}); }) ); @@ -462,9 +462,9 @@ describe('Update SV Reward Weight Form', () => { test('should send reward weight to backend without underscore', async () => { let requestBody = ''; server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, async (req, res, ctx) => { - requestBody = await req.text(); - return res(ctx.json({})); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, async ({ request }) => { + requestBody = await request.text(); + return HttpResponse.json({}); }) ); diff --git a/apps/sv/frontend/src/__tests__/governance/proposal-details-content.test.tsx b/apps/sv/frontend/src/__tests__/governance/proposal-details-content.test.tsx index f108d35118..ad1590977a 100644 --- a/apps/sv/frontend/src/__tests__/governance/proposal-details-content.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/proposal-details-content.test.tsx @@ -18,7 +18,7 @@ import { import userEvent from '@testing-library/user-event'; import { SvConfigProvider } from '../../utils'; import { server, svUrl } from '../setup/setup'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { ProposalVoteForm } from '../../components/governance/ProposalVoteForm'; import App from '../../App'; import { svPartyId } from '../mocks/constants'; @@ -867,8 +867,8 @@ describe('Proposal Details > Votes & Voting', () => { ]; server.use( - rest.post(`${svUrl}/v0/admin/sv/votes`, (_, res, ctx) => { - return res(ctx.status(201)); + http.post(`${svUrl}/v0/admin/sv/votes`, () => { + return new HttpResponse(null, { status: 201 }); }) ); @@ -930,8 +930,8 @@ describe('Proposal Details > Votes & Voting', () => { ]; server.use( - rest.post(`${svUrl}/v0/admin/sv/votes`, (_, res, ctx) => { - return res(ctx.status(400)); + http.post(`${svUrl}/v0/admin/sv/votes`, () => { + return new HttpResponse(null, { status: 400 }); }) ); diff --git a/apps/sv/frontend/src/__tests__/mocks/browser.ts b/apps/sv/frontend/src/__tests__/mocks/browser.ts index 0daa09abfa..2adde4910c 100644 --- a/apps/sv/frontend/src/__tests__/mocks/browser.ts +++ b/apps/sv/frontend/src/__tests__/mocks/browser.ts @@ -1,6 +1,6 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { setupWorker, SetupWorker } from 'msw'; +import { setupWorker, SetupWorker } from 'msw/browser'; import { buildSvMock } from './handlers/sv-api'; diff --git a/apps/sv/frontend/src/__tests__/mocks/handlers/sv-api.ts b/apps/sv/frontend/src/__tests__/mocks/handlers/sv-api.ts index 5f3cecfb54..5364b3828b 100644 --- a/apps/sv/frontend/src/__tests__/mocks/handlers/sv-api.ts +++ b/apps/sv/frontend/src/__tests__/mocks/handlers/sv-api.ts @@ -5,7 +5,7 @@ import { dsoInfoHandler, } from '@lfdecentralizedtrust/splice-common-test-handlers'; import dayjs from 'dayjs'; -import { rest, RestHandler } from 'msw'; +import { http, HttpHandler, HttpResponse, PathParams } from 'msw'; import { FeatureSupportResponse, SuccessStatusResponse } from '@lfdecentralizedtrust/scan-openapi'; import { ErrorResponse, @@ -13,6 +13,7 @@ import { ListDsoRulesVoteResultsResponse, ListFeaturedAppRightsByProviderResponse, ListOngoingValidatorOnboardingsResponse, + ListVoteResultsRequest, LookupFeaturedAppRightByContractIdResponse, ListVoteRequestByTrackingCidResponse, LookupDsoRulesVoteRequestResponse, @@ -28,30 +29,28 @@ import { import { ValidatorOnboarding } from '@daml.js/splice-validator-lifecycle/lib/Splice/ValidatorOnboarding/module'; import { ContractId } from '@daml/types'; -export const buildSvMock = (svUrl: string): RestHandler[] => [ - rest.get(`${svUrl}/v0/admin/authorization`, (_, res, ctx) => { - return res(ctx.status(200)); +export const buildSvMock = (svUrl: string): HttpHandler[] => [ + http.get(`${svUrl}/v0/admin/authorization`, () => { + return new HttpResponse(null, { status: 200 }); }), dsoInfoHandler(svUrl), - rest.get(`${svUrl}/v0/admin/sv/voterequests`, (_, res, ctx) => { - return res(ctx.json(voteRequests)); + http.get(`${svUrl}/v0/admin/sv/voterequests`, () => { + return HttpResponse.json(voteRequests); }), - rest.get(`${svUrl}/v0/admin/sv/voterequests/:id`, (req, res, ctx) => { - const { id } = req.params; - return res( - ctx.json({ - dso_rules_vote_request: voteRequests.dso_rules_vote_requests.filter( - vr => vr.contract_id === id - )[0], - }) - ); + http.get(`${svUrl}/v0/admin/sv/voterequests/:id`, ({ params }) => { + const { id } = params; + return HttpResponse.json({ + dso_rules_vote_request: voteRequests.dso_rules_vote_requests.filter( + vr => vr.contract_id === id + )[0], + }); }), - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, (_, res, ctx) => { - return res(ctx.json({})); + http.post(`${svUrl}/v0/admin/sv/voterequest/create`, () => { + return HttpResponse.json({}); // Use this to test a failed response // return res( @@ -62,15 +61,16 @@ export const buildSvMock = (svUrl: string): RestHandler[] => [ // ); }), - rest.post(`${svUrl}/v0/admin/sv/voterequest`, (_, res, ctx) => { - return res(ctx.json(voteRequest)); + http.post(`${svUrl}/v0/admin/sv/voterequest`, () => { + return HttpResponse.json(voteRequest); }), - rest.post(`${svUrl}/v0/admin/sv/voteresults`, (req, res, ctx) => { - return req.json().then(data => { - if (data.actionName === 'SRARC_SetConfig') { - return res( - ctx.json({ + http.post( + `${svUrl}/v0/admin/sv/voteresults`, + ({ request }) => { + return request.json().then(data => { + if (data.actionName === 'SRARC_SetConfig') { + return HttpResponse.json({ dso_rules_vote_results: voteResultsDsoRules.dso_rules_vote_results .filter( r => @@ -85,11 +85,9 @@ export const buildSvMock = (svUrl: string): RestHandler[] => [ : true) ) .slice(0, data.limit || 10), - }) - ); - } else if (data.actionName === 'CRARC_AddFutureAmuletConfigSchedule') { - return res( - ctx.json({ + }); + } else if (data.actionName === 'CRARC_AddFutureAmuletConfigSchedule') { + return HttpResponse.json({ dso_rules_vote_results: voteResultsAmuletRules.dso_rules_vote_results .filter( r => @@ -108,155 +106,143 @@ export const buildSvMock = (svUrl: string): RestHandler[] => [ : true) ) .slice(0, data.limit || 10), - }) - ); - } else if (data.actionName === 'CRARC_UpdateFutureAmuletConfigSchedule') { - return res( - ctx.json({ + }); + } else if (data.actionName === 'CRARC_UpdateFutureAmuletConfigSchedule') { + return HttpResponse.json({ dso_rules_vote_results: [], - }) - ); - } else { - // Simulate cursor-based pagination using descending synthetic entry_numbers. - // Each result is assigned an entry_number equal to (total - index), so the - // first result has the highest entry_number and the last has entry_number 1. - const allResults = voteResultsAmuletRules.dso_rules_vote_results - .concat(voteResultsDsoRules.dso_rules_vote_results) - .filter(r => { - const acceptedMatch = - data.accepted === undefined || data.accepted === null - ? true - : data.accepted - ? r.outcome.tag === 'VRO_Accepted' - : r.outcome.tag === 'VRO_Rejected'; - const effectiveToMatch = data.effectiveTo - ? r.outcome.value - ? dayjs(r.outcome.value.effectiveAt).isBefore(dayjs(data.effectiveTo)) - : dayjs(r.completedAt).isBefore(dayjs(data.effectiveTo)) - : true; - const effectiveFromMatch = data.effectiveFrom - ? r.outcome.value - ? dayjs(r.outcome.value.effectiveAt).isAfter(dayjs(data.effectiveFrom)) - : dayjs(r.completedAt).isAfter(dayjs(data.effectiveFrom)) - : true; - return acceptedMatch && effectiveToMatch && effectiveFromMatch; }); - const total = allResults.length; - const cursor = data.pageToken; - // Find the starting index: skip results whose entry_number >= cursor - const startIndex = - cursor !== undefined && cursor !== null - ? allResults.findIndex((_, i) => total - i < cursor) - : 0; - const limit = data.limit || 10; - const paged = allResults.slice(startIndex, startIndex + limit); - const lastEntryNumber = - paged.length > 0 ? total - (startIndex + paged.length - 1) : undefined; - const hasMore = startIndex + paged.length < total; - return res( - ctx.json({ + } else { + // Simulate cursor-based pagination using descending synthetic entry_numbers. + // Each result is assigned an entry_number equal to (total - index), so the + // first result has the highest entry_number and the last has entry_number 1. + const allResults = voteResultsAmuletRules.dso_rules_vote_results + .concat(voteResultsDsoRules.dso_rules_vote_results) + .filter(r => { + const acceptedMatch = + data.accepted === undefined || data.accepted === null + ? true + : data.accepted + ? r.outcome.tag === 'VRO_Accepted' + : r.outcome.tag === 'VRO_Rejected'; + const effectiveToMatch = data.effectiveTo + ? r.outcome.value + ? dayjs(r.outcome.value.effectiveAt).isBefore(dayjs(data.effectiveTo)) + : dayjs(r.completedAt).isBefore(dayjs(data.effectiveTo)) + : true; + const effectiveFromMatch = data.effectiveFrom + ? r.outcome.value + ? dayjs(r.outcome.value.effectiveAt).isAfter(dayjs(data.effectiveFrom)) + : dayjs(r.completedAt).isAfter(dayjs(data.effectiveFrom)) + : true; + return acceptedMatch && effectiveToMatch && effectiveFromMatch; + }); + const total = allResults.length; + const cursor = data.pageToken; + // Find the starting index: skip results whose entry_number >= cursor + const startIndex = + cursor !== undefined && cursor !== null + ? allResults.findIndex((_, i) => total - i < cursor) + : 0; + const limit = data.limit || 10; + const paged = allResults.slice(startIndex, startIndex + limit); + const lastEntryNumber = + paged.length > 0 ? total - (startIndex + paged.length - 1) : undefined; + const hasMore = startIndex + paged.length < total; + return HttpResponse.json({ dso_rules_vote_results: paged, ...(hasMore && lastEntryNumber !== undefined ? { next_page_token: lastEntryNumber } : {}), - }) - ); - } - }); - }), + }); + } + }); + } + ), - rest.post(`${svUrl}/v0/admin/sv/votes`, (_, res, ctx) => { - return res(ctx.status(201)); + http.post(`${svUrl}/v0/admin/sv/votes`, () => { + return new HttpResponse(null, { status: 201 }); }), - rest.get(`${svUrl}/v0/admin/domain/cometbft/debug`, (_, res, ctx) => { - return res( - ctx.status(404), - ctx.json({ + http.get(`${svUrl}/v0/admin/domain/cometbft/debug`, () => { + return HttpResponse.json( + { error: `No domain nodes in this test.`, - }) + }, + { status: 404 } ); }), - rest.get(`${svUrl}/v0/admin/domain/sequencer/status`, (_, res, ctx) => { - return res( - ctx.json({ - success: { - id: 'global-domain::1990be58c99e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb999a', - uptime: 'PT26H38.219973S', - ports: { - public: 5008, - admin: 5009, - }, - active: true, + http.get(`${svUrl}/v0/admin/domain/sequencer/status`, () => { + return HttpResponse.json({ + success: { + id: 'global-domain::1990be58c99e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb999a', + uptime: 'PT26H38.219973S', + ports: { + public: 5008, + admin: 5009, }, - }) - ); + active: true, + }, + }); }), - rest.get(`${svUrl}/v0/admin/domain/mediator/status`, (_, res, ctx) => { - return res( - ctx.json({ - success: { - id: 'global-domain::1990be58c99e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb999a', - uptime: 'PT26H38.219973S', - ports: { - public: 5008, - admin: 5009, - }, - active: true, + http.get(`${svUrl}/v0/admin/domain/mediator/status`, () => { + return HttpResponse.json({ + success: { + id: 'global-domain::1990be58c99e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb999a', + uptime: 'PT26H38.219973S', + ports: { + public: 5008, + admin: 5009, }, - }) - ); + active: true, + }, + }); }), - rest.get(`${svUrl}/v0/admin/feature-support`, (_, res, ctx) => { - return res(ctx.json({})); + http.get(`${svUrl}/v0/admin/feature-support`, () => { + return HttpResponse.json({}); }), validatorLicensesHandler(svUrl), - rest.get(`${svUrl}/v0/admin/validator/onboarding/ongoing`, (_, res, ctx) => { - return res( - ctx.json({ - ongoing_validator_onboardings: [ - { - encoded_secret: 'encoded_secret', - contract: { - template_id: - '455dd4533c2dd0131fb349c93d9d35f3670901d13efadb0aa9b975d35b41dbb2:Splice.ValidatorOnboarding:ValidatorOnboarding', - contract_id: 'validatorOnboardingCid' as ContractId, - payload: { - sv: 'svParty', - candidateSecret: 'candidate_secret', - expiresAt: '2024-08-05T13:44:35.878681Z', - }, - created_event_blob: '', - created_at: '2024-08-05T13:44:35.878681Z', + http.get(`${svUrl}/v0/admin/validator/onboarding/ongoing`, () => { + return HttpResponse.json({ + ongoing_validator_onboardings: [ + { + encoded_secret: 'encoded_secret', + contract: { + template_id: + '455dd4533c2dd0131fb349c93d9d35f3670901d13efadb0aa9b975d35b41dbb2:Splice.ValidatorOnboarding:ValidatorOnboarding', + contract_id: 'validatorOnboardingCid' as ContractId, + payload: { + sv: 'svParty', + candidateSecret: 'candidate_secret', + expiresAt: '2024-08-05T13:44:35.878681Z', }, + created_event_blob: '', + created_at: '2024-08-05T13:44:35.878681Z', }, - ], - }) - ); + }, + ], + }); }), - rest.get(`${svUrl}/v0/admin/sv/party-to-participant/:partyId`, (req, res, ctx) => { - const normalizedPartyId = decodeURIComponent(String(req.params.partyId)); + http.get(`${svUrl}/v0/admin/sv/party-to-participant/:partyId`, ({ params }) => { + const normalizedPartyId = decodeURIComponent(String(params.partyId)); if (normalizedPartyId === 'a-party-id::1014912492' || normalizedPartyId === svPartyId) { - return res( - ctx.json({ - participant_ids: [svPartyId], - }) - ); + return HttpResponse.json({ + participant_ids: [svPartyId], + }); } else { - return res(ctx.status(404)); + return new HttpResponse(null, { status: 404 }); } }), - rest.get( + http.get( `${svUrl}/v0/admin/sv/featured-app-rights/by-provider/:providerPartyId`, - (req, res, ctx) => { - const providerPartyId = decodeURIComponent(String(req.params.providerPartyId)); + ({ params }) => { + const providerPartyId = decodeURIComponent(String(params.providerPartyId)); const featuredAppRights = providerPartyId === 'a-party-id::1014912492' ? [ @@ -270,34 +256,27 @@ export const buildSvMock = (svUrl: string): RestHandler[] => [ ] : []; - return res( - ctx.json({ - featured_app_rights: featuredAppRights, - }) - ); + return HttpResponse.json({ + featured_app_rights: featuredAppRights, + }); } ), - rest.get( - `${svUrl}/v0/admin/sv/featured-app-rights/by-contract-id/:contractId`, - (req, res, ctx) => { - const contractId = decodeURIComponent(String(req.params.contractId)); - const featuredAppRight = - contractId === 'rightCid123' - ? { - template_id: 'featured-app-right-template-id', - contract_id: 'rightCid123', - payload: { provider: 'a-party-id::1014912492' }, - created_event_blob: '', - created_at: '2026-02-26T13:00:00.000000Z', - } - : undefined; + http.get(`${svUrl}/v0/admin/sv/featured-app-rights/by-contract-id/:contractId`, ({ params }) => { + const contractId = decodeURIComponent(String(params.contractId)); + const featuredAppRight = + contractId === 'rightCid123' + ? { + template_id: 'featured-app-right-template-id', + contract_id: 'rightCid123', + payload: { provider: 'a-party-id::1014912492' }, + created_event_blob: '', + created_at: '2026-02-26T13:00:00.000000Z', + } + : undefined; - return res( - ctx.json({ - featured_app_right: featuredAppRight, - }) - ); - } - ), + return HttpResponse.json({ + featured_app_right: featuredAppRight, + }); + }), ]; diff --git a/apps/sv/frontend/src/__tests__/setup/setup.ts b/apps/sv/frontend/src/__tests__/setup/setup.ts index 01388aab7f..6ca1317163 100644 --- a/apps/sv/frontend/src/__tests__/setup/setup.ts +++ b/apps/sv/frontend/src/__tests__/setup/setup.ts @@ -1,5 +1,16 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 + +// happy-dom@20 doesn't lowercase header names during iteration as the Fetch +// spec requires; the openapi clients read `headers["content-type"]`, so without +// this patch they fail to parse JSON responses from MSW. +const _origForEach = Headers.prototype.forEach; +Headers.prototype.forEach = function (cb, thisArg) { + return _origForEach.call(this, function (value: string, name: string, parent: Headers) { + cb.call(thisArg, value, name.toLowerCase(), parent); + }); +}; + import '@testing-library/jest-dom/vitest'; import { cleanup } from '@testing-library/react'; import crypto from 'crypto'; diff --git a/apps/sv/frontend/src/__tests__/sv.test.tsx b/apps/sv/frontend/src/__tests__/sv.test.tsx index bfcf16cc8c..beaebbbacd 100644 --- a/apps/sv/frontend/src/__tests__/sv.test.tsx +++ b/apps/sv/frontend/src/__tests__/sv.test.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { rest } from 'msw'; +import { http, HttpResponse, PathParams } from 'msw'; import { mockAllIsIntersecting } from 'react-intersection-observer/test-utils'; import { CreateVoteRequest, @@ -251,8 +251,8 @@ describe('An SetConfig request', () => { test('disables the Proceed button in the confirmation dialog if a conflict arises after request creation', async () => { server.use( - rest.get(`${svUrl}/v0/admin/sv/voterequests`, (_, res, ctx) => { - return res(ctx.json({ dso_rules_vote_requests: [] })); + http.get(`${svUrl}/v0/admin/sv/voterequests`, () => { + return HttpResponse.json({ dso_rules_vote_requests: [] }); }) ); @@ -281,8 +281,8 @@ describe('An SetConfig request', () => { await user.click(screen.getByText('Send Request to Super Validators')); server.use( - rest.get(`${svUrl}/v0/admin/sv/voterequests`, (_, res, ctx) => { - return res(ctx.json(voteRequests)); + http.get(`${svUrl}/v0/admin/sv/voterequests`, () => { + return HttpResponse.json(voteRequests); }) ); @@ -335,10 +335,13 @@ describe('SetAmuletRules', () => { resolve => (calledCreate = resolve) ); server.use( - rest.post(`${svUrl}/v0/admin/sv/voterequest/create`, async (req, res, ctx) => { - calledCreate(await req.json()); - return res(ctx.json({})); - }) + http.post( + `${svUrl}/v0/admin/sv/voterequest/create`, + async ({ request }) => { + calledCreate(await request.json()); + return HttpResponse.json({}); + } + ) ); const user = userEvent.setup(); diff --git a/apps/sv/frontend/src/__tests__/synchroniser-upgrade.test.tsx b/apps/sv/frontend/src/__tests__/synchroniser-upgrade.test.tsx index 75b54e3ac5..92542c0ba0 100644 --- a/apps/sv/frontend/src/__tests__/synchroniser-upgrade.test.tsx +++ b/apps/sv/frontend/src/__tests__/synchroniser-upgrade.test.tsx @@ -5,7 +5,7 @@ import { render, screen, fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import dayjs from 'dayjs'; import timezone from 'dayjs/plugin/timezone'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { test, expect, describe } from 'vitest'; import App from '../App'; @@ -66,8 +66,8 @@ describe('SV user can', () => { test('set next scheduled synchronizer upgrade', async () => { server.use( - rest.get(`${svUrl}/v0/dso`, (_, res, ctx) => { - return res(ctx.json(dsoInfoWithoutSynchronizerUpgrade)); + http.get(`${svUrl}/v0/dso`, () => { + return HttpResponse.json(dsoInfoWithoutSynchronizerUpgrade); }) ); @@ -94,8 +94,8 @@ describe('SV user can', () => { test('submit vote request with new valid synchronizer upgrade time', async () => { server.use( - rest.get(`${svUrl}/v0/dso`, (_, res, ctx) => { - return res(ctx.json(dsoInfoWithoutSynchronizerUpgrade)); + http.get(`${svUrl}/v0/dso`, () => { + return HttpResponse.json(dsoInfoWithoutSynchronizerUpgrade); }) ); @@ -142,8 +142,8 @@ describe('SV user can', () => { test('submit vote request with existing and unchanged synchronizer upgrade time', async () => { server.use( - rest.get(`${svUrl}/v0/dso`, (_, res, ctx) => { - return res(ctx.json(dsoInfoWithSynchronizerUpgrade)); + http.get(`${svUrl}/v0/dso`, () => { + return HttpResponse.json(dsoInfoWithSynchronizerUpgrade); }) ); @@ -169,8 +169,8 @@ describe('SV user can', () => { test('not submit vote request if new synchronizer upgrade time is before expiry', async () => { server.use( - rest.get(`${svUrl}/v0/dso`, (_, res, ctx) => { - return res(ctx.json(dsoInfoWithoutSynchronizerUpgrade)); + http.get(`${svUrl}/v0/dso`, () => { + return HttpResponse.json(dsoInfoWithoutSynchronizerUpgrade); }) ); @@ -225,8 +225,8 @@ describe('SV user can', () => { test('not submit vote request if synchronizer upgrade time is changed and is before expiry and effective at threshold', async () => { server.use( - rest.get(`${svUrl}/v0/dso`, (_, res, ctx) => { - return res(ctx.json(dsoInfoWithSynchronizerUpgrade)); + http.get(`${svUrl}/v0/dso`, () => { + return HttpResponse.json(dsoInfoWithSynchronizerUpgrade); }) ); @@ -282,8 +282,8 @@ describe('SV user can', () => { test('not submit vote request if synchronizer upgrade time is changed and is before effective date', async () => { server.use( - rest.get(`${svUrl}/v0/dso`, (_, res, ctx) => { - return res(ctx.json(dsoInfoWithSynchronizerUpgrade)); + http.get(`${svUrl}/v0/dso`, () => { + return HttpResponse.json(dsoInfoWithSynchronizerUpgrade); }) ); @@ -339,8 +339,8 @@ describe('SV user can', () => { 'make changes with different timezones', async () => { server.use( - rest.get(`${svUrl}/v0/dso`, (_, res, ctx) => { - return res(ctx.json(dsoInfoWithoutSynchronizerUpgrade)); + http.get(`${svUrl}/v0/dso`, () => { + return HttpResponse.json(dsoInfoWithoutSynchronizerUpgrade); }) ); diff --git a/apps/wallet/frontend/package.json b/apps/wallet/frontend/package.json index 2367d77420..4b403643f2 100644 --- a/apps/wallet/frontend/package.json +++ b/apps/wallet/frontend/package.json @@ -14,21 +14,26 @@ ] }, "dependencies": { - "@daml.js/splice-api-token-metadata": "file:../../common/frontend/daml.js/splice-api-token-metadata-v1-1.0.0", "@daml.js/splice-api-token-allocation": "file:../../common/frontend/daml.js/splice-api-token-allocation-v1-1.0.0", "@daml.js/splice-api-token-allocation-request": "file:../../common/frontend/daml.js/splice-api-token-allocation-request-v1-1.0.0", + "@daml.js/splice-api-token-metadata": "file:../../common/frontend/daml.js/splice-api-token-metadata-v1-1.0.0", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", + "@lfdecentralizedtrust/scan-proxy-openapi": "^0.0.1", + "@lfdecentralizedtrust/splice-common-frontend": "0.1.0", + "@lfdecentralizedtrust/splice-common-frontend-utils": "0.1.0", "@mui/icons-material": "^7.3.4", "@mui/material": "^7.3.4", "@tanstack/react-query": "5.90.20", "bignumber.js": "9.1.1", - "@lfdecentralizedtrust/splice-common-frontend": "0.1.0", - "@lfdecentralizedtrust/splice-common-frontend-utils": "0.1.0", + "dompurify": "^3.4.2", + "jose": "^4.15.9", + "jsondiffpatch": "^0.7.3", "react": "18.3.1", "react-dom": "18.3.1", "react-helmet-async": "^2.0.5", - "@lfdecentralizedtrust/scan-proxy-openapi": "^0.0.1" + "uuid": "^14.0.0", + "zod": "^3.25.76" }, "devDependencies": { "@eslint/js": "^9.24.0", @@ -46,7 +51,7 @@ "@typescript-eslint/eslint-plugin": "8.29.1", "@typescript-eslint/parser": "8.29.1", "@vitejs/plugin-react": "^6.0.1", - "eslint": "9.24.0", + "eslint": "^9.39.4", "eslint-config-prettier": "10.1.1", "eslint-plugin-import": "2.31.0", "eslint-plugin-jsx-a11y": "6.10.2", @@ -54,7 +59,7 @@ "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", "happy-dom": "^20.0.11", - "msw": "^1.2.5", + "msw": "^2.14.2", "prettier": "3.5.3", "typescript": "5.8.3", "typescript-eslint": "^8.30.1", diff --git a/apps/wallet/frontend/src/__tests__/developmentFund.test.tsx b/apps/wallet/frontend/src/__tests__/developmentFund.test.tsx index a5759495b0..f81025a0b8 100644 --- a/apps/wallet/frontend/src/__tests__/developmentFund.test.tsx +++ b/apps/wallet/frontend/src/__tests__/developmentFund.test.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { describe, expect, test, vi } from 'vitest'; import App from '../App'; @@ -84,44 +84,40 @@ describe('Development Fund page', () => { test('applies allocation amount validation', async () => { server.use( - rest.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, (_, res, ctx) => { - return res( - ctx.json({ - ...amuletRules, - amulet_rules: { - ...amuletRules.amulet_rules, - contract: { - ...amuletRules.amulet_rules.contract, - payload: { - ...amuletRules.amulet_rules.contract.payload, - configSchedule: { - ...amuletRules.amulet_rules.contract.payload.configSchedule, - initialValue: { - ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, - optDevelopmentFundManager: alicePartyId, - }, + http.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, () => { + return HttpResponse.json({ + ...amuletRules, + amulet_rules: { + ...amuletRules.amulet_rules, + contract: { + ...amuletRules.amulet_rules.contract, + payload: { + ...amuletRules.amulet_rules.contract.payload, + configSchedule: { + ...amuletRules.amulet_rules.contract.payload.configSchedule, + initialValue: { + ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, + optDevelopmentFundManager: alicePartyId, }, }, }, }, - }) - ); + }, + }); }), - rest.get(`${walletUrl}/v0/scan-proxy/unclaimed-development-fund-coupons`, (_, res, ctx) => { - return res( - ctx.json({ - unclaimed_development_fund_coupons: [ - { - contract: { - payload: { - amount: '10.0', - }, + http.get(`${walletUrl}/v0/scan-proxy/unclaimed-development-fund-coupons`, () => { + return HttpResponse.json({ + unclaimed_development_fund_coupons: [ + { + contract: { + payload: { + amount: '10.0', }, - domain_id: 'domain-0', }, - ], - }) - ); + domain_id: 'domain-0', + }, + ], + }); }) ); @@ -140,44 +136,40 @@ describe('Development Fund page', () => { test('shows amount helper text when allocation amount is zero', async () => { server.use( - rest.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, (_, res, ctx) => { - return res( - ctx.json({ - ...amuletRules, - amulet_rules: { - ...amuletRules.amulet_rules, - contract: { - ...amuletRules.amulet_rules.contract, - payload: { - ...amuletRules.amulet_rules.contract.payload, - configSchedule: { - ...amuletRules.amulet_rules.contract.payload.configSchedule, - initialValue: { - ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, - optDevelopmentFundManager: alicePartyId, - }, + http.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, () => { + return HttpResponse.json({ + ...amuletRules, + amulet_rules: { + ...amuletRules.amulet_rules, + contract: { + ...amuletRules.amulet_rules.contract, + payload: { + ...amuletRules.amulet_rules.contract.payload, + configSchedule: { + ...amuletRules.amulet_rules.contract.payload.configSchedule, + initialValue: { + ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, + optDevelopmentFundManager: alicePartyId, }, }, }, }, - }) - ); + }, + }); }), - rest.get(`${walletUrl}/v0/scan-proxy/unclaimed-development-fund-coupons`, (_, res, ctx) => { - return res( - ctx.json({ - unclaimed_development_fund_coupons: [ - { - contract: { - payload: { - amount: '10.0', - }, + http.get(`${walletUrl}/v0/scan-proxy/unclaimed-development-fund-coupons`, () => { + return HttpResponse.json({ + unclaimed_development_fund_coupons: [ + { + contract: { + payload: { + amount: '10.0', }, - domain_id: 'domain-0', }, - ], - }) - ); + domain_id: 'domain-0', + }, + ], + }); }) ); @@ -197,28 +189,26 @@ describe('Development Fund page', () => { test('applies allocation expiration date validation', async () => { server.use( - rest.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, (_, res, ctx) => { - return res( - ctx.json({ - ...amuletRules, - amulet_rules: { - ...amuletRules.amulet_rules, - contract: { - ...amuletRules.amulet_rules.contract, - payload: { - ...amuletRules.amulet_rules.contract.payload, - configSchedule: { - ...amuletRules.amulet_rules.contract.payload.configSchedule, - initialValue: { - ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, - optDevelopmentFundManager: alicePartyId, - }, + http.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, () => { + return HttpResponse.json({ + ...amuletRules, + amulet_rules: { + ...amuletRules.amulet_rules, + contract: { + ...amuletRules.amulet_rules.contract, + payload: { + ...amuletRules.amulet_rules.contract.payload, + configSchedule: { + ...amuletRules.amulet_rules.contract.payload.configSchedule, + initialValue: { + ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, + optDevelopmentFundManager: alicePartyId, }, }, }, }, - }) - ); + }, + }); }) ); @@ -239,47 +229,43 @@ describe('Development Fund page', () => { test('renders development fund history table view', async () => { server.use( - rest.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, (_, res, ctx) => { - return res( - ctx.json({ - ...amuletRules, - amulet_rules: { - ...amuletRules.amulet_rules, - contract: { - ...amuletRules.amulet_rules.contract, - payload: { - ...amuletRules.amulet_rules.contract.payload, - configSchedule: { - ...amuletRules.amulet_rules.contract.payload.configSchedule, - initialValue: { - ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, - optDevelopmentFundManager: alicePartyId, - }, + http.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, () => { + return HttpResponse.json({ + ...amuletRules, + amulet_rules: { + ...amuletRules.amulet_rules, + contract: { + ...amuletRules.amulet_rules.contract, + payload: { + ...amuletRules.amulet_rules.contract.payload, + configSchedule: { + ...amuletRules.amulet_rules.contract.payload.configSchedule, + initialValue: { + ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, + optDevelopmentFundManager: alicePartyId, }, }, }, }, - }) - ); + }, + }); }), - rest.get(`${walletUrl}/v0/wallet/development-fund-coupons/history`, (_, res, ctx) => { - return res( - ctx.json({ - development_fund_coupon_history: [ - { - createdAt: '2026-01-01T10:00:00.000Z', - archivedAt: '2026-01-02T11:00:00.000Z', - beneficiary: alicePartyId, - fund_manager: bobPartyId, - amount: '3.0', - expiresAt: '2026-01-10T11:00:00.000Z', - reason: 'Infrastructure improvements', - status: 'withdrawn', - rejection_or_withdrawal_reason: 'No longer needed', - }, - ], - }) - ); + http.get(`${walletUrl}/v0/wallet/development-fund-coupons/history`, () => { + return HttpResponse.json({ + development_fund_coupon_history: [ + { + createdAt: '2026-01-01T10:00:00.000Z', + archivedAt: '2026-01-02T11:00:00.000Z', + beneficiary: alicePartyId, + fund_manager: bobPartyId, + amount: '3.0', + expiresAt: '2026-01-10T11:00:00.000Z', + reason: 'Infrastructure improvements', + status: 'withdrawn', + rejection_or_withdrawal_reason: 'No longer needed', + }, + ], + }); }) ); @@ -292,35 +278,31 @@ describe('Development Fund page', () => { test('renders empty development fund history table view', async () => { server.use( - rest.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, (_, res, ctx) => { - return res( - ctx.json({ - ...amuletRules, - amulet_rules: { - ...amuletRules.amulet_rules, - contract: { - ...amuletRules.amulet_rules.contract, - payload: { - ...amuletRules.amulet_rules.contract.payload, - configSchedule: { - ...amuletRules.amulet_rules.contract.payload.configSchedule, - initialValue: { - ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, - optDevelopmentFundManager: alicePartyId, - }, + http.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, () => { + return HttpResponse.json({ + ...amuletRules, + amulet_rules: { + ...amuletRules.amulet_rules, + contract: { + ...amuletRules.amulet_rules.contract, + payload: { + ...amuletRules.amulet_rules.contract.payload, + configSchedule: { + ...amuletRules.amulet_rules.contract.payload.configSchedule, + initialValue: { + ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, + optDevelopmentFundManager: alicePartyId, }, }, }, }, - }) - ); + }, + }); }), - rest.get(`${walletUrl}/v0/wallet/development-fund-coupons/history`, (_, res, ctx) => { - return res( - ctx.json({ - development_fund_coupon_history: [], - }) - ); + http.get(`${walletUrl}/v0/wallet/development-fund-coupons/history`, () => { + return HttpResponse.json({ + development_fund_coupon_history: [], + }); }) ); @@ -332,28 +314,26 @@ describe('Development Fund page', () => { test('renders unclaimed development fund allocations table view', async () => { server.use( - rest.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, (_, res, ctx) => { - return res( - ctx.json({ - ...amuletRules, - amulet_rules: { - ...amuletRules.amulet_rules, - contract: { - ...amuletRules.amulet_rules.contract, - payload: { - ...amuletRules.amulet_rules.contract.payload, - configSchedule: { - ...amuletRules.amulet_rules.contract.payload.configSchedule, - initialValue: { - ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, - optDevelopmentFundManager: alicePartyId, - }, + http.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, () => { + return HttpResponse.json({ + ...amuletRules, + amulet_rules: { + ...amuletRules.amulet_rules, + contract: { + ...amuletRules.amulet_rules.contract, + payload: { + ...amuletRules.amulet_rules.contract.payload, + configSchedule: { + ...amuletRules.amulet_rules.contract.payload.configSchedule, + initialValue: { + ...amuletRules.amulet_rules.contract.payload.configSchedule.initialValue, + optDevelopmentFundManager: alicePartyId, }, }, }, }, - }) - ); + }, + }); }) ); diff --git a/apps/wallet/frontend/src/__tests__/logout.test.tsx b/apps/wallet/frontend/src/__tests__/logout.test.tsx index 70ec5e3395..a384b95a90 100644 --- a/apps/wallet/frontend/src/__tests__/logout.test.tsx +++ b/apps/wallet/frontend/src/__tests__/logout.test.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { describe, expect, test } from 'vitest'; import { UserStatusResponse } from '@lfdecentralizedtrust/wallet-openapi'; @@ -14,15 +14,13 @@ import { server } from './setup/setup'; const walletUrl = window.splice_config.services.validator.url; function userStatusHandler(user_onboarded: boolean) { - return rest.get(`${walletUrl}/v0/wallet/user-status`, (_, res, ctx) => { - return res( - ctx.json({ - party_id: alicePartyId, - user_onboarded: user_onboarded, - user_wallet_installed: true, - has_featured_app_right: false, - }) - ); + return http.get(`${walletUrl}/v0/wallet/user-status`, () => { + return HttpResponse.json({ + party_id: alicePartyId, + user_onboarded: user_onboarded, + user_wallet_installed: true, + has_featured_app_right: false, + }); }); } @@ -72,8 +70,8 @@ describe('Logout button appears', () => { test('when the api is not responding', async () => { server.use( - rest.get(`${walletUrl}/v0/wallet/user-status`, (_, res, ctx) => { - return res(ctx.status(404)); + http.get(`${walletUrl}/v0/wallet/user-status`, () => { + return new HttpResponse(null, { status: 404 }); }) ); const user = userEvent.setup(); diff --git a/apps/wallet/frontend/src/__tests__/mocks/browser.ts b/apps/wallet/frontend/src/__tests__/mocks/browser.ts index 0d774dfe2a..b32b61fa25 100644 --- a/apps/wallet/frontend/src/__tests__/mocks/browser.ts +++ b/apps/wallet/frontend/src/__tests__/mocks/browser.ts @@ -1,6 +1,6 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { setupWorker, SetupWorker } from 'msw'; +import { setupWorker, SetupWorker } from 'msw/browser'; import { config } from '../setup/config'; import { buildWalletMock } from './handlers/wallet-api'; diff --git a/apps/wallet/frontend/src/__tests__/mocks/handlers/transfers-api.ts b/apps/wallet/frontend/src/__tests__/mocks/handlers/transfers-api.ts index 5e51ddb0da..9e50cee35a 100644 --- a/apps/wallet/frontend/src/__tests__/mocks/handlers/transfers-api.ts +++ b/apps/wallet/frontend/src/__tests__/mocks/handlers/transfers-api.ts @@ -1,6 +1,6 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { rest, RestHandler } from 'msw'; +import { http, HttpHandler, HttpResponse } from 'msw'; import { Mock, vi } from 'vitest'; export const requestMocks: { @@ -20,24 +20,24 @@ export const requestMocks: { }; // We need to separate the api endpoints that use vitest to avoid compatibility errors with msw. -export const buildTransferOfferMock = (walletUrl: string): RestHandler[] => [ - rest.post(`${walletUrl}/v0/wallet/transfer-offers`, async (req, res, ctx) => { - await requestMocks.createTransferOffer(await req.json()); - return res(ctx.json({})); +export const buildTransferOfferMock = (walletUrl: string): HttpHandler[] => [ + http.post(`${walletUrl}/v0/wallet/transfer-offers`, async ({ request }) => { + await requestMocks.createTransferOffer(await request.json()); + return HttpResponse.json({}); }), - rest.post(`${walletUrl}/v0/wallet/token-standard/transfers`, async (req, res, ctx) => { - await requestMocks.createTransferViaTokenStandard(await req.json()); - return res(ctx.json({})); + http.post(`${walletUrl}/v0/wallet/token-standard/transfers`, async ({ request }) => { + await requestMocks.createTransferViaTokenStandard(await request.json()); + return HttpResponse.json({}); }), - rest.post(`${walletUrl}/v0/wallet/transfer-preapproval`, async (_, res, ctx) => { + http.post(`${walletUrl}/v0/wallet/transfer-preapproval`, async () => { await requestMocks.createTransferPreapproval(); - return res(ctx.json({})); + return HttpResponse.json({}); }), - rest.post(`${walletUrl}/v0/wallet/transfer-preapproval/send`, async (req, res, ctx) => { - await requestMocks.transferPreapprovalSend(await req.json()); - return res(ctx.json({})); + http.post(`${walletUrl}/v0/wallet/transfer-preapproval/send`, async ({ request }) => { + await requestMocks.transferPreapprovalSend(await request.json()); + return HttpResponse.json({}); }), ]; diff --git a/apps/wallet/frontend/src/__tests__/mocks/handlers/wallet-api.ts b/apps/wallet/frontend/src/__tests__/mocks/handlers/wallet-api.ts index 31467207e6..1f6368e936 100644 --- a/apps/wallet/frontend/src/__tests__/mocks/handlers/wallet-api.ts +++ b/apps/wallet/frontend/src/__tests__/mocks/handlers/wallet-api.ts @@ -1,6 +1,6 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { RestHandler, rest } from 'msw'; +import { http, HttpHandler, HttpResponse } from 'msw'; import { LookupTransferPreapprovalByPartyResponse } from '@lfdecentralizedtrust/scan-openapi'; import { GetAmuletRulesProxyResponse, @@ -37,251 +37,227 @@ import { } from '../delegation-constants'; import { mkContract } from '../contract'; -export const buildWalletMock = (walletUrl: string): RestHandler[] => [ - rest.get(`${walletUrl}/v0/wallet/user-status`, (_, res, ctx) => { - return res( - ctx.json({ - party_id: alicePartyId, - user_onboarded: true, - user_wallet_installed: true, - has_featured_app_right: false, - }) - ); +export const buildWalletMock = (walletUrl: string): HttpHandler[] => [ + http.get(`${walletUrl}/v0/wallet/user-status`, () => { + return HttpResponse.json({ + party_id: alicePartyId, + user_onboarded: true, + user_wallet_installed: true, + has_featured_app_right: false, + }); }), - rest.get( + http.get( `${walletUrl}/v0/scan-proxy/featured-apps/alice__wallet__user%3A%3A12201d5aa725ec9491490fd860e86f849358604f6fd387053771cafb90384a94c3e2`, - (_, res, ctx) => { - return res(ctx.json({ featured_app_right: null })); + () => { + return HttpResponse.json({ featured_app_right: null }); } ), - rest.get(`${walletUrl}/v0/scan-proxy/open-and-issuing-mining-rounds`, (_, res, ctx) => { - return res(ctx.json(miningRounds)); + http.get(`${walletUrl}/v0/scan-proxy/open-and-issuing-mining-rounds`, () => { + return HttpResponse.json(miningRounds); }), - rest.get(`${walletUrl}/v0/scan-proxy/ans-entries`, (_, res, ctx) => { - return res( - ctx.json({ - entries: nameServiceEntries, - }) - ); + http.get(`${walletUrl}/v0/scan-proxy/ans-entries`, () => { + return HttpResponse.json({ + entries: nameServiceEntries, + }); }), - rest.get(`${walletUrl}/v0/scan-proxy/ans-entries/by-party/:party`, (req, res, ctx) => { - const { party } = req.params; + http.get(`${walletUrl}/v0/scan-proxy/ans-entries/by-party/:party`, ({ params }) => { + const { party } = params; if ( party === 'alice__wallet__user::12201d5aa725ec9491490fd860e86f849358604f6fd387053771cafb90384a94c3e2' ) { - return res( - ctx.json({ - entry: aliceEntry, - }) - ); + return HttpResponse.json({ + entry: aliceEntry, + }); } else { - return res(ctx.status(404), ctx.json({})); + return HttpResponse.json({}, { status: 404 }); } }), - rest.get(`${walletUrl}/v0/scan-proxy/ans-entries/by-name/:name`, (_, res, ctx) => { - return res(ctx.status(404), ctx.json({})); + http.get(`${walletUrl}/v0/scan-proxy/ans-entries/by-name/:name`, () => { + return HttpResponse.json({}, { status: 404 }); }), - rest.get(`${walletUrl}/v0/sample`, (_, res, ctx) => { - return res(ctx.json({})); + http.get(`${walletUrl}/v0/sample`, () => { + return HttpResponse.json({}); }), - rest.get(`${walletUrl}/v0/scan-proxy/transfer-preapprovals/by-party/:party`, (req, res, ctx) => { - const { party } = req.params; + http.get(`${walletUrl}/v0/scan-proxy/transfer-preapprovals/by-party/:party`, ({ params }) => { + const { party } = params; if (party === 'bob::preapproval') { - return res( - ctx.json({ - transfer_preapproval: bobTransferPreapproval, - }) - ); + return HttpResponse.json({ + transfer_preapproval: bobTransferPreapproval, + }); } - return res(ctx.status(404), ctx.json({})); + return HttpResponse.json({}, { status: 404 }); }), - rest.get(`${walletUrl}/v0/scan-proxy/transfer-preapprovals/by-party`, (_req, res, ctx) => { + http.get(`${walletUrl}/v0/scan-proxy/transfer-preapprovals/by-party`, () => { // The by-party request above seems to not match for an empty party string - return res(ctx.status(404), ctx.json({})); + return HttpResponse.json({}, { status: 404 }); }), - rest.get(`${walletUrl}/v0/wallet/balance`, (_, res, ctx) => { - return res( - ctx.json({ - round: 18, - effective_unlocked_qty: '778.9353119400', - effective_locked_qty: '0.0000000000', - total_holding_fees: '0.0646880600', - }) - ); + http.get(`${walletUrl}/v0/wallet/balance`, () => { + return HttpResponse.json({ + round: 18, + effective_unlocked_qty: '778.9353119400', + effective_locked_qty: '0.0000000000', + total_holding_fees: '0.0646880600', + }); }), - rest.post(`${walletUrl}/v0/wallet/transactions`, (_, res, ctx) => { - return res( - ctx.json({ - items: [ - { - transaction_type: 'balance_change', - transaction_subtype: { - template_id: - '#splice-amulet:Splice.AmuletTransferInstruction:AmuletTransferInstruction', - choice: 'TransferInstruction_Withdraw', - }, - event_id: '#u4:0', - date: new Date('2025-05-21T12:14:12Z'), - receivers: [{ party: alicePartyId, amount: '0.0' }], - transfer_instruction_cid: - '009a97ffdf201d323d12a428187d9118d985678c37c6c1081f848269943f0da8bbca1112207e4b3e9a65879126e8b8103714f0144e1e0218fa98fb5231c63be74a0bb40402', - - // the openapi generator seems to generate a garbage type so there are a bunch of non-sense fields we need to fill in - sender: { party: '', amount: '' }, - holding_fees: '', - app_rewards_used: '', - validator_rewards_used: '', - sv_rewards_used: '', - development_fund_coupons_used: '', - details: '', + http.post(`${walletUrl}/v0/wallet/transactions`, () => { + return HttpResponse.json({ + items: [ + { + transaction_type: 'balance_change', + transaction_subtype: { + template_id: + '#splice-amulet:Splice.AmuletTransferInstruction:AmuletTransferInstruction', + choice: 'TransferInstruction_Withdraw', }, - // incoming - { - transaction_type: 'transfer', - transaction_subtype: { - template_id: - '#splice-amulet:Splice.ExternalPartyAmuletRules:ExternalPartyAmuletRules', - choice: 'TransferFactory_Transfer', - }, - event_id: '#u3:0', - date: new Date('2025-05-21T12:14:12Z'), - sender: { party: bobPartyId, amount: '-42.0' }, - receivers: [{ party: alicePartyId, amount: '0.0' }], - holding_fees: '0.0', - app_rewards_used: '0.0', - validator_rewards_used: '0.0', - sv_rewards_used: '0.0', - details: '', - transfer_instruction_cid: - '009a97ffdf201d323d12a428187d9118d985678c37c6c1081f848269943f0da8bbca1112207e4b3e9a65879126e8b8103714f0144e1e0218fa98fb5231c63be74a0bb40402', - transfer_instruction_receiver: alicePartyId, - transfer_instruction_amount: '10.0', - description: 'test transfer', - development_fund_coupons_used: '0.0', + event_id: '#u4:0', + date: new Date('2025-05-21T12:14:12Z'), + receivers: [{ party: alicePartyId, amount: '0.0' }], + transfer_instruction_cid: + '009a97ffdf201d323d12a428187d9118d985678c37c6c1081f848269943f0da8bbca1112207e4b3e9a65879126e8b8103714f0144e1e0218fa98fb5231c63be74a0bb40402', + + // the openapi generator seems to generate a garbage type so there are a bunch of non-sense fields we need to fill in + sender: { party: '', amount: '' }, + holding_fees: '', + app_rewards_used: '', + validator_rewards_used: '', + sv_rewards_used: '', + development_fund_coupons_used: '', + details: '', + }, + // incoming + { + transaction_type: 'transfer', + transaction_subtype: { + template_id: '#splice-amulet:Splice.ExternalPartyAmuletRules:ExternalPartyAmuletRules', + choice: 'TransferFactory_Transfer', }, - { - transaction_type: 'transfer', - transaction_subtype: { - template_id: - '#splice-amulet:Splice.AmuletTransferInstruction:AmuletTransferInstruction', - choice: 'TransferInstruction_Accept', - }, - event_id: '#u2:0', - date: new Date('2025-05-21T12:12:12Z'), - sender: { party: alicePartyId, amount: '23.0' }, - receivers: [], - holding_fees: '0.0', - app_rewards_used: '0.0', - validator_rewards_used: '0.0', - sv_rewards_used: '0.0', - development_fund_coupons_used: '0.0', - details: '', - transfer_instruction_cid: - '009a97ffdf201d323d12a428187d9118d985678c37c6c1081f848269943f0da8bbca1112207e4b3e9a65879126e8b8103714f0144e1e0218fa98fb5231c63be74a0bb40401', + event_id: '#u3:0', + date: new Date('2025-05-21T12:14:12Z'), + sender: { party: bobPartyId, amount: '-42.0' }, + receivers: [{ party: alicePartyId, amount: '0.0' }], + holding_fees: '0.0', + app_rewards_used: '0.0', + validator_rewards_used: '0.0', + sv_rewards_used: '0.0', + details: '', + transfer_instruction_cid: + '009a97ffdf201d323d12a428187d9118d985678c37c6c1081f848269943f0da8bbca1112207e4b3e9a65879126e8b8103714f0144e1e0218fa98fb5231c63be74a0bb40402', + transfer_instruction_receiver: alicePartyId, + transfer_instruction_amount: '10.0', + description: 'test transfer', + development_fund_coupons_used: '0.0', + }, + { + transaction_type: 'transfer', + transaction_subtype: { + template_id: + '#splice-amulet:Splice.AmuletTransferInstruction:AmuletTransferInstruction', + choice: 'TransferInstruction_Accept', }, - // outgoing - { - transaction_type: 'transfer', - transaction_subtype: { - template_id: - '#splice-amulet:Splice.ExternalPartyAmuletRules:ExternalPartyAmuletRules', - choice: 'TransferFactory_Transfer', - }, - event_id: '#u1:0', - date: new Date('2025-05-21T12:10:12Z'), - sender: { party: alicePartyId, amount: '-42.0' }, - receivers: [], - holding_fees: '0.0', - app_rewards_used: '0.0', - validator_rewards_used: '0.0', - sv_rewards_used: '0.0', - development_fund_coupons_used: '0.0', - details: '', - transfer_instruction_cid: - '009a97ffdf201d323d12a428187d9118d985678c37c6c1081f848269943f0da8bbca1112207e4b3e9a65879126e8b8103714f0144e1e0218fa98fb5231c63be74a0bb40401', - transfer_instruction_receiver: bobPartyId, - transfer_instruction_amount: '10.0', - description: 'test transfer', + event_id: '#u2:0', + date: new Date('2025-05-21T12:12:12Z'), + sender: { party: alicePartyId, amount: '23.0' }, + receivers: [], + holding_fees: '0.0', + app_rewards_used: '0.0', + validator_rewards_used: '0.0', + sv_rewards_used: '0.0', + development_fund_coupons_used: '0.0', + details: '', + transfer_instruction_cid: + '009a97ffdf201d323d12a428187d9118d985678c37c6c1081f848269943f0da8bbca1112207e4b3e9a65879126e8b8103714f0144e1e0218fa98fb5231c63be74a0bb40401', + }, + // outgoing + { + transaction_type: 'transfer', + transaction_subtype: { + template_id: '#splice-amulet:Splice.ExternalPartyAmuletRules:ExternalPartyAmuletRules', + choice: 'TransferFactory_Transfer', }, - ], - }) - ); + event_id: '#u1:0', + date: new Date('2025-05-21T12:10:12Z'), + sender: { party: alicePartyId, amount: '-42.0' }, + receivers: [], + holding_fees: '0.0', + app_rewards_used: '0.0', + validator_rewards_used: '0.0', + sv_rewards_used: '0.0', + development_fund_coupons_used: '0.0', + details: '', + transfer_instruction_cid: + '009a97ffdf201d323d12a428187d9118d985678c37c6c1081f848269943f0da8bbca1112207e4b3e9a65879126e8b8103714f0144e1e0218fa98fb5231c63be74a0bb40401', + transfer_instruction_receiver: bobPartyId, + transfer_instruction_amount: '10.0', + description: 'test transfer', + }, + ], + }); }), - rest.get(`${walletUrl}/v0/wallet/transfer-offers`, (_, res, ctx) => { - return res(ctx.json({ offers: [] })); + http.get(`${walletUrl}/v0/wallet/transfer-offers`, () => { + return HttpResponse.json({ offers: [] }); }), - rest.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, (_, res, ctx) => { - return res(ctx.json(amuletRules)); + http.get(`${walletUrl}/v0/scan-proxy/amulet-rules`, () => { + return HttpResponse.json(amuletRules); }), - rest.get(`${walletUrl}/v0/scan-proxy/unclaimed-development-fund-coupons`, (_, res, ctx) => { - return res( - ctx.json({ - unclaimed_development_fund_coupons: [], - }) - ); + http.get(`${walletUrl}/v0/scan-proxy/unclaimed-development-fund-coupons`, () => { + return HttpResponse.json({ + unclaimed_development_fund_coupons: [], + }); }), - rest.get(`${walletUrl}/v0/wallet/development-fund-coupons`, (_, res, ctx) => { - return res( - ctx.json({ - active_development_fund_coupons: [], - }) - ); + http.get(`${walletUrl}/v0/wallet/development-fund-coupons`, () => { + return HttpResponse.json({ + active_development_fund_coupons: [], + }); }), - rest.get(`${walletUrl}/v0/wallet/development-fund-coupons/history`, (_, res, ctx) => { - return res( - ctx.json({ - development_fund_coupon_history: [], - }) - ); + http.get(`${walletUrl}/v0/wallet/development-fund-coupons/history`, () => { + return HttpResponse.json({ + development_fund_coupon_history: [], + }); }), - rest.get(`${walletUrl}/v0/scan-proxy/featured-apps/:party`, (_, res, ctx) => { - return res(ctx.status(404), ctx.json({})); + http.get(`${walletUrl}/v0/scan-proxy/featured-apps/:party`, () => { + return HttpResponse.json({}, { status: 404 }); }), - rest.get(`${walletUrl}/v0/wallet/minting-delegations`, (_, res, ctx) => { - return res( - ctx.json({ - delegations: mockMintingDelegations.map((delegation, index) => ({ - contract: mkContract(MintingDelegation, delegation), - beneficiary_hosted: mockDelegationHostedStatus[index], - })), - }) - ); + http.get(`${walletUrl}/v0/wallet/minting-delegations`, () => { + return HttpResponse.json({ + delegations: mockMintingDelegations.map((delegation, index) => ({ + contract: mkContract(MintingDelegation, delegation), + beneficiary_hosted: mockDelegationHostedStatus[index], + })), + }); }), - rest.get(`${walletUrl}/v0/wallet/minting-delegation-proposals`, (_, res, ctx) => { - return res( - ctx.json({ - proposals: mockMintingDelegationProposals.map((proposal, index) => ({ - contract: mkContract(MintingDelegationProposal, proposal), - beneficiary_hosted: mockProposalHostedStatus[index], - })), - }) - ); + http.get(`${walletUrl}/v0/wallet/minting-delegation-proposals`, () => { + return HttpResponse.json({ + proposals: mockMintingDelegationProposals.map((proposal, index) => ({ + contract: mkContract(MintingDelegationProposal, proposal), + beneficiary_hosted: mockProposalHostedStatus[index], + })), + }); }), - rest.post(`${walletUrl}/v0/wallet/minting-delegations/:cid/reject`, (_, res, ctx) => { - return res(ctx.status(200)); + http.post(`${walletUrl}/v0/wallet/minting-delegations/:cid/reject`, () => { + return new HttpResponse(null, { status: 200 }); }), - rest.post(`${walletUrl}/v0/wallet/minting-delegation-proposals/:cid/accept`, (_, res, ctx) => { - return res(ctx.status(200)); + http.post(`${walletUrl}/v0/wallet/minting-delegation-proposals/:cid/accept`, () => { + return new HttpResponse(null, { status: 200 }); }), - rest.post(`${walletUrl}/v0/wallet/minting-delegation-proposals/:cid/reject`, (_, res, ctx) => { - return res(ctx.status(200)); + http.post(`${walletUrl}/v0/wallet/minting-delegation-proposals/:cid/reject`, () => { + return new HttpResponse(null, { status: 200 }); }), ]; diff --git a/apps/wallet/frontend/src/__tests__/setup/setup.ts b/apps/wallet/frontend/src/__tests__/setup/setup.ts index c21aa2a286..2093b8ee73 100644 --- a/apps/wallet/frontend/src/__tests__/setup/setup.ts +++ b/apps/wallet/frontend/src/__tests__/setup/setup.ts @@ -1,5 +1,16 @@ // Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 + +// happy-dom@20 doesn't lowercase header names during iteration as the Fetch +// spec requires; the openapi clients read `headers["content-type"]`, so without +// this patch they fail to parse JSON responses from MSW. +const _origForEach = Headers.prototype.forEach; +Headers.prototype.forEach = function (cb, thisArg) { + return _origForEach.call(this, function (value: string, name: string, parent: Headers) { + cb.call(thisArg, value, name.toLowerCase(), parent); + }); +}; + import '@testing-library/jest-dom/vitest'; import { cleanup } from '@testing-library/react'; import crypto from 'crypto'; diff --git a/apps/wallet/frontend/src/__tests__/wallet.test.tsx b/apps/wallet/frontend/src/__tests__/wallet.test.tsx index b3bb8b6eaa..0f0a8a2a96 100644 --- a/apps/wallet/frontend/src/__tests__/wallet.test.tsx +++ b/apps/wallet/frontend/src/__tests__/wallet.test.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { rest } from 'msw'; +import { http, HttpResponse, PathParams } from 'msw'; import { LookupTransferPreapprovalByPartyResponse } from '@lfdecentralizedtrust/scan-openapi'; import { test, expect, describe } from 'vitest'; import { vi } from 'vitest'; @@ -54,13 +54,11 @@ function featureSupportHandler( tokenStandardSupported: boolean, transferPreapprovalDescriptionSupported: boolean ) { - return rest.get(`${walletUrl}/v0/feature-support`, async (_, res, ctx) => { - return res( - ctx.json({ - token_standard: tokenStandardSupported, - transfer_preapproval_description: transferPreapprovalDescriptionSupported, - }) - ); + return http.get(`${walletUrl}/v0/feature-support`, async () => { + return HttpResponse.json({ + token_standard: tokenStandardSupported, + transfer_preapproval_description: transferPreapprovalDescriptionSupported, + }); }); } @@ -130,18 +128,16 @@ describe('Wallet user can', () => { expect(requestMocks.createTransferPreapproval).toHaveBeenCalled(); // Mock the request to fetch the created pre-approval server.use( - rest.get( + http.get( `${window.splice_config.services.validator.url}/v0/scan-proxy/transfer-preapprovals/by-party/:party`, - (req, res, ctx) => { - const { party } = req.params; + ({ params }) => { + const { party } = params; if (party === alicePartyId) { - return res( - ctx.json({ - transfer_preapproval: aliceTransferPreapproval, - }) - ); + return HttpResponse.json({ + transfer_preapproval: aliceTransferPreapproval, + }); } else { - return res(ctx.status(404), ctx.json({})); + return HttpResponse.json({}, { status: 404 }); } } ) @@ -233,16 +229,14 @@ describe('Wallet user can', () => { ) ); server.use( - rest.get(`${walletUrl}/v0/allocations`, (_req, res, ctx) => { - return res( - ctx.json({ - allocations: allocations.map(allocationPayload => { - return { - contract: mkContract(AmuletAllocation, allocationPayload), - }; - }), - }) - ); + http.get(`${walletUrl}/v0/allocations`, () => { + return HttpResponse.json({ + allocations: allocations.map(allocationPayload => { + return { + contract: mkContract(AmuletAllocation, allocationPayload), + }; + }), + }); }) ); @@ -274,24 +268,17 @@ describe('Wallet user can', () => { resolve => (calledCreate = resolve) ); server.use( - rest.get( - `${walletUrl}/v0/wallet/token-standard/allocation-requests`, - (_req, res, ctx) => { - return res( - ctx.json({ - allocation_requests: allocationRequests.map(contract => { - return { contract: mkContract(AllocationRequest, contract) }; - }), - }) - ); - } - ), - rest.get(`${walletUrl}/v0/allocations`, (_req, res, ctx) => { - return res( - ctx.json({ - allocations: [], - }) - ); + http.get(`${walletUrl}/v0/wallet/token-standard/allocation-requests`, () => { + return HttpResponse.json({ + allocation_requests: allocationRequests.map(contract => { + return { contract: mkContract(AllocationRequest, contract) }; + }), + }); + }), + http.get(`${walletUrl}/v0/allocations`, () => { + return HttpResponse.json({ + allocations: [], + }); }) ); @@ -320,20 +307,23 @@ describe('Wallet user can', () => { expect(acceptButtons.length).toBe(1); server.use( - rest.post(`${walletUrl}/v0/allocations`, async (req, res, ctx) => { - const body = await req.json(); - calledCreate(body); - const response: AllocateAmuletResponse = { - output: { - allocation_instruction_cid: 'alloc_instr_cid', - allocation_cid: 'alloc_cid', - dummy: {}, - }, - sender_change_cids: ['whatever'], - meta: {}, - }; - return res(ctx.json(response)); - }) + http.post( + `${walletUrl}/v0/allocations`, + async ({ request }) => { + const body = await request.json(); + calledCreate(body); + const response: AllocateAmuletResponse = { + output: { + allocation_instruction_cid: 'alloc_instr_cid', + allocation_cid: 'alloc_cid', + dummy: {}, + }, + sender_change_cids: ['whatever'], + meta: {}, + }; + return HttpResponse.json(response); + } + ) ); acceptButtons[0].click(); @@ -365,35 +355,26 @@ describe('Wallet user can', () => { const calledWithdrawArgs: string[] = []; server.use( - rest.get( - `${walletUrl}/v0/wallet/token-standard/allocation-requests`, - (_req, res, ctx) => { - return res( - ctx.json({ - allocation_requests: allocationRequests.map(contract => { - return { contract }; - }), - }) - ); - } - ), - rest.get(`${walletUrl}/v0/allocations`, (_req, res, ctx) => { - return res( - ctx.json({ - allocations: allocations.map(contract => { - return { contract }; - }), - }) - ); + http.get(`${walletUrl}/v0/wallet/token-standard/allocation-requests`, () => { + return HttpResponse.json({ + allocation_requests: allocationRequests.map(contract => { + return { contract }; + }), + }); }), - rest.post(`${walletUrl}/v0/allocations/:cid/withdraw`, (req, res, ctx) => { - calledWithdrawArgs.push(req.params.cid.toString()); - return res( - ctx.json({ - sender_holding_cids: [], - meta: {}, - }) - ); + http.get(`${walletUrl}/v0/allocations`, () => { + return HttpResponse.json({ + allocations: allocations.map(contract => { + return { contract }; + }), + }); + }), + http.post<{ cid: string }>(`${walletUrl}/v0/allocations/:cid/withdraw`, ({ params }) => { + calledWithdrawArgs.push(params.cid); + return HttpResponse.json({ + sender_holding_cids: [], + meta: {}, + }); }) ); @@ -432,34 +413,25 @@ describe('Wallet user can', () => { const calledRejectArgs: string[] = []; server.use( - rest.get( - `${walletUrl}/v0/wallet/token-standard/allocation-requests`, - (_req, res, ctx) => { - return res( - ctx.json({ - allocation_requests: allocationRequests.map(contract => { - return { contract }; - }), - }) - ); - } - ), - rest.get(`${walletUrl}/v0/allocations`, (_req, res, ctx) => { - return res( - ctx.json({ - allocations: [], - }) - ); + http.get(`${walletUrl}/v0/wallet/token-standard/allocation-requests`, () => { + return HttpResponse.json({ + allocation_requests: allocationRequests.map(contract => { + return { contract }; + }), + }); }), - rest.post( + http.get(`${walletUrl}/v0/allocations`, () => { + return HttpResponse.json({ + allocations: [], + }); + }), + http.post<{ cid: string }>( `${walletUrl}/v0/wallet/token-standard/allocation-requests/:cid/reject`, - (req, res, ctx) => { - calledRejectArgs.push(req.params.cid.toString()); - return res( - ctx.json({ - meta: {}, - }) - ); + ({ params }) => { + calledRejectArgs.push(params.cid); + return HttpResponse.json({ + meta: {}, + }); } ) ); @@ -636,11 +608,11 @@ describe('Wallet user can', () => { server.use(featureSupportHandler(true, true)); // Override endpoints to return empty lists server.use( - rest.get(`${walletUrl}/v0/wallet/minting-delegations`, (_, res, ctx) => { - return res(ctx.json({ delegations: [] })); + http.get(`${walletUrl}/v0/wallet/minting-delegations`, () => { + return HttpResponse.json({ delegations: [] }); }), - rest.get(`${walletUrl}/v0/wallet/minting-delegation-proposals`, (_, res, ctx) => { - return res(ctx.json({ proposals: [] })); + http.get(`${walletUrl}/v0/wallet/minting-delegation-proposals`, () => { + return HttpResponse.json({ proposals: [] }); }) ); @@ -675,10 +647,13 @@ describe('Wallet user can', () => { // Track the cancel API call const calledCancelArgs: string[] = []; server.use( - rest.post(`${walletUrl}/v0/wallet/minting-delegations/:cid/reject`, (req, res, ctx) => { - calledCancelArgs.push(req.params.cid.toString()); - return res(ctx.status(200)); - }) + http.post<{ cid: string }>( + `${walletUrl}/v0/wallet/minting-delegations/:cid/reject`, + ({ params }) => { + calledCancelArgs.push(params.cid); + return new HttpResponse(null, { status: 200 }); + } + ) ); const user = userEvent.setup(); @@ -711,11 +686,11 @@ describe('Wallet user can', () => { const calledArgs: string[] = []; server.use( - rest.post( + http.post<{ cid: string }>( `${walletUrl}/v0/wallet/minting-delegation-proposals/:cid/accept`, - (req, res, ctx) => { - calledArgs.push(req.params.cid.toString()); - return res(ctx.status(200)); + ({ params }) => { + calledArgs.push(params.cid); + return new HttpResponse(null, { status: 200 }); } ) ); @@ -747,11 +722,11 @@ describe('Wallet user can', () => { const calledArgs: string[] = []; server.use( - rest.post( + http.post<{ cid: string }>( `${walletUrl}/v0/wallet/minting-delegation-proposals/:cid/reject`, - (req, res, ctx) => { - calledArgs.push(req.params.cid.toString()); - return res(ctx.status(200)); + ({ params }) => { + calledArgs.push(params.cid); + return new HttpResponse(null, { status: 200 }); } ) ); @@ -783,11 +758,11 @@ describe('Wallet user can', () => { const calledAcceptArgs: string[] = []; server.use( - rest.post( + http.post<{ cid: string }>( `${walletUrl}/v0/wallet/minting-delegation-proposals/:cid/accept`, - (req, res, ctx) => { - calledAcceptArgs.push(req.params.cid.toString()); - return res(ctx.status(200)); + ({ params }) => { + calledAcceptArgs.push(params.cid); + return new HttpResponse(null, { status: 200 }); } ) );