diff --git a/.github/workflows/fastgpt-test.yaml b/.github/workflows/fastgpt-test.yaml new file mode 100644 index 000000000..069a26201 --- /dev/null +++ b/.github/workflows/fastgpt-test.yaml @@ -0,0 +1,29 @@ +name: 'FastGPT-Test' +on: + pull_request: + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + permissions: + # Required to checkout the code + contents: read + # Required to put a comment into the pull-request + pull-requests: write + + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10 + - name: 'Install Deps' + run: pnpm install + - name: 'Test' + run: pnpm run test + - name: 'Report Coverage' + # Set if: always() to also generate the report if tests are failing + # Only works if you set `reportOnFailure: true` in your vite config as specified above + if: always() + uses: davelosert/vitest-coverage-report-action@v2 diff --git a/.gitignore b/.gitignore index 5be731c50..ec9cb7ca9 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ files/helm/fastgpt/fastgpt-0.1.0.tgz files/helm/fastgpt/charts/*.tgz tmp/ +coverage diff --git a/package.json b/package.json index 655f00e15..31fd2fe8d 100644 --- a/package.json +++ b/package.json @@ -11,16 +11,22 @@ "initIcon": "node ./scripts/icon/init.js", "previewIcon": "node ./scripts/icon/index.js", "api:gen": "tsc ./scripts/openapi/index.ts && node ./scripts/openapi/index.js && npx @redocly/cli build-docs ./scripts/openapi/openapi.json -o ./projects/app/public/openapi/index.html", - "create:i18n": "node ./scripts/i18n/index.js" + "create:i18n": "node ./scripts/i18n/index.js", + "test": "vitest run --exclude './projects/app/src/test/**'", + "test:all": "vitest run", + "test:workflow": "vitest run workflow" }, "devDependencies": { "@chakra-ui/cli": "^2.4.1", + "@vitest/coverage-v8": "^3.0.2", "husky": "^8.0.3", - "lint-staged": "^13.3.0", "i18next": "23.11.5", + "lint-staged": "^13.3.0", "next-i18next": "15.3.0", - "react-i18next": "14.1.2", "prettier": "3.2.4", + "react-i18next": "14.1.2", + "vitest": "^3.0.2", + "vitest-mongodb": "^1.0.1", "zhlint": "^0.7.4" }, "lint-staged": { diff --git a/projects/app/src/pages/api/v1/chat/utils.test.ts b/packages/service/core/ai/utils.test.ts similarity index 97% rename from projects/app/src/pages/api/v1/chat/utils.test.ts rename to packages/service/core/ai/utils.test.ts index 95071d261..77e2f9166 100644 --- a/projects/app/src/pages/api/v1/chat/utils.test.ts +++ b/packages/service/core/ai/utils.test.ts @@ -1,5 +1,5 @@ -import '@/pages/api/__mocks__/base'; -import { parseReasoningStreamContent } from '@fastgpt/service/core/ai/utils'; +import { parseReasoningStreamContent } from './utils'; +import { expect, test } from 'vitest'; test('Parse reasoning stream content test', async () => { const partList = [ diff --git a/packages/service/test/utils.ts b/packages/service/test/utils.ts deleted file mode 100644 index 933cf7487..000000000 --- a/packages/service/test/utils.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { ERROR_ENUM } from '@fastgpt/global/common/error/errorCode'; - -export type TestTokenType = { - userId: string; - teamId: string; - tmbId: string; - isRoot: boolean; -}; - -export type TestRequest = { - headers: { - cookie?: { - token?: TestTokenType; - }; - authorization?: string; // testkey - rootkey?: string; // rootkey - }; - query: { - [key: string]: string; - }; - body: { - [key: string]: string; - }; -}; - -export function getTestRequest({ - query = {}, - body = {}, - authToken = true, - // authRoot = false, - // authApiKey = false, - user -}: { - query?: Partial; - body?: Partial; - authToken?: boolean; - authRoot?: boolean; - authApiKey?: boolean; - user?: { - uid: string; - tmbId: string; - teamId: string; - isRoot: boolean; - }; -}): [any, any] { - const headers: TestRequest['headers'] = {}; - if (authToken) { - headers.cookie = { - token: { - userId: String(user?.uid || ''), - teamId: String(user?.teamId || ''), - tmbId: String(user?.tmbId || ''), - isRoot: user?.isRoot || false - } - }; - } - return [ - { - headers, - query, - body - }, - {} - ]; -} - -export const parseHeaderCertMock = async ({ - req, - authToken = true, - authRoot = false, - authApiKey = false -}: { - req: TestRequest; - authToken?: boolean; - authRoot?: boolean; - authApiKey?: boolean; -}): Promise => { - if (authToken) { - const token = req.headers?.cookie?.token; - if (!token) { - return Promise.reject(ERROR_ENUM.unAuthorization); - } - return token; - } - // if (authRoot) { - // // TODO: unfinished - // return req.headers.rootkey; - // } - // if (authApiKey) { - // // TODO: unfinished - // return req.headers.authorization; - // } - return {} as any; -}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index feebb6656..e2492a00e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@chakra-ui/cli': specifier: ^2.4.1 version: 2.4.1 + '@vitest/coverage-v8': + specifier: 3.0.5 + version: 3.0.5(vitest@3.0.5(@types/debug@4.1.12)(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3)) husky: specifier: ^8.0.3 version: 8.0.3 @@ -29,9 +32,15 @@ importers: react-i18next: specifier: 14.1.2 version: 14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + vitest: + specifier: ^3.0.2 + version: 3.0.5(@types/debug@4.1.12)(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3) + vitest-mongodb: + specifier: ^1.0.1 + version: 1.0.1(socks@2.8.3) zhlint: specifier: ^0.7.4 - version: 0.7.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3)(typescript@5.5.3) + version: 0.7.4(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3)(typescript@5.5.3) packages/global: dependencies: @@ -288,6 +297,27 @@ importers: specifier: workspace:* version: link:../service + packages/test: + devDependencies: + '@testing-library/dom': + specifier: ^10.4.0 + version: 10.4.0 + '@testing-library/react': + specifier: ^16.2.0 + version: 16.2.0(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.3.4(vite@5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3)) + jsdom: + specifier: ^26.0.0 + version: 26.0.0 + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.5.3)(vite@5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3)) + vitest: + specifier: ^3.0.2 + version: 3.0.5(@types/debug@4.1.12)(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3) + packages/web: dependencies: '@chakra-ui/anatomy': @@ -590,7 +620,7 @@ importers: version: 1.77.8 ts-jest: specifier: ^29.1.0 - version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0))(typescript@5.5.3) use-context-selector: specifier: ^1.4.4 version: 1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2) @@ -652,6 +682,9 @@ importers: typescript: specifier: ^5.1.3 version: 5.5.3 + vitest: + specifier: ^3.0.2 + version: 3.0.5(@types/debug@4.1.12)(@types/node@20.14.11)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3) projects/sandbox: dependencies: @@ -733,7 +766,7 @@ importers: version: 6.3.4 ts-jest: specifier: ^29.1.0 - version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0))(typescript@5.5.3) ts-loader: specifier: ^9.4.3 version: 9.5.1(typescript@5.5.3)(webpack@5.92.1) @@ -792,6 +825,9 @@ packages: peerDependencies: openapi-types: '>=7' + '@asamuzakjp/css-color@2.8.3': + resolution: {integrity: sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==} + '@azure/abort-controller@2.1.2': resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} engines: {node: '>=18.0.0'} @@ -864,14 +900,26 @@ packages: resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.24.9': resolution: {integrity: sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.26.8': + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + engines: {node: '>=6.9.0'} + '@babel/core@7.24.9': resolution: {integrity: sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==} engines: {node: '>=6.9.0'} + '@babel/core@7.26.8': + resolution: {integrity: sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.24.10': resolution: {integrity: sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==} engines: {node: '>=6.9.0'} @@ -880,6 +928,10 @@ packages: resolution: {integrity: sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.26.8': + resolution: {integrity: sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.24.7': resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} engines: {node: '>=6.9.0'} @@ -892,6 +944,10 @@ packages: resolution: {integrity: sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.26.5': + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.24.8': resolution: {integrity: sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==} engines: {node: '>=6.9.0'} @@ -929,12 +985,22 @@ packages: resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.24.9': resolution: {integrity: sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.24.7': resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} engines: {node: '>=6.9.0'} @@ -943,6 +1009,10 @@ packages: resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + engines: {node: '>=6.9.0'} + '@babel/helper-remap-async-to-generator@7.24.7': resolution: {integrity: sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==} engines: {node: '>=6.9.0'} @@ -971,14 +1041,26 @@ packages: resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.24.8': resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + '@babel/helper-wrap-function@7.24.7': resolution: {integrity: sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==} engines: {node: '>=6.9.0'} @@ -987,6 +1069,10 @@ packages: resolution: {integrity: sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.26.7': + resolution: {integrity: sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==} + engines: {node: '>=6.9.0'} + '@babel/highlight@7.24.7': resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} @@ -1001,6 +1087,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.26.8': + resolution: {integrity: sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7': resolution: {integrity: sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==} engines: {node: '>=6.9.0'} @@ -1384,6 +1475,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-self@7.25.9': + resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.25.9': + resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx@7.24.7': resolution: {integrity: sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==} engines: {node: '>=6.9.0'} @@ -1510,6 +1613,10 @@ packages: resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} engines: {node: '>=6.9.0'} + '@babel/template@7.26.8': + resolution: {integrity: sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.24.8': resolution: {integrity: sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==} engines: {node: '>=6.9.0'} @@ -1518,6 +1625,10 @@ packages: resolution: {integrity: sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.26.8': + resolution: {integrity: sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.24.9': resolution: {integrity: sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==} engines: {node: '>=6.9.0'} @@ -1526,12 +1637,20 @@ packages: resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} engines: {node: '>=6.9.0'} + '@babel/types@7.26.8': + resolution: {integrity: sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==} + engines: {node: '>=6.9.0'} + '@bany/curl-to-json@1.2.8': resolution: {integrity: sha512-hPt9KUM2sGZ5Ojx3O9utjzUgjRZI3CZPAlLf+cRY9EUzVs7tWt1OpA0bhEUTX2PEEkOeyZ6sC0tAQMOHh9ld+Q==} '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + '@braintree/sanitize-url@6.0.4': resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} @@ -2038,6 +2157,34 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@csstools/color-helpers@5.0.1': + resolution: {integrity: sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.1': + resolution: {integrity: sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-color-parser@3.0.7': + resolution: {integrity: sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-parser-algorithms@3.0.4': + resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-tokenizer@3.0.3': + resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} + engines: {node: '>=18'} + '@dabh/diagnostics@2.0.3': resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} @@ -3294,6 +3441,25 @@ packages: '@tediousjs/connection-string@0.5.0': resolution: {integrity: sha512-7qSgZbincDDDFyRweCIEvZULFAw5iz/DeunhvuxpL31nfntX3P4Yd4HkHBRg9H8CdqY1e5WFN1PZIz/REL9MVQ==} + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/react@16.2.0': + resolution: {integrity: sha512-2cSskAvA1QNtKc8Y9VJQRv0tm3hLVgxRGDB+KYhIaPQJ1I+RHbhIXcM+zClKXzMes/wshsMVzf4B9vS4IZpqDQ==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} @@ -3316,6 +3482,9 @@ packages: '@tybys/wasm-util@0.8.3': resolution: {integrity: sha512-Z96T/L6dUFFxgFJ+pQtkPpne9q7i6kIPYCFnQBHSgSPV9idTsKfIhCss0h5iM9irweZCatkrdeP8yi5uM1eX6Q==} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -3463,6 +3632,9 @@ packages: '@types/formidable@2.0.6': resolution: {integrity: sha512-L4HcrA05IgQyNYJj6kItuIkXrInJvsXTPC5B1i64FggWKKqSL+4hgt7asiSNva75AoLQjq29oPxFfU4GAQ6Z2w==} + '@types/gensync@1.0.4': + resolution: {integrity: sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==} + '@types/geojson@7946.0.14': resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==} @@ -3719,21 +3891,65 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vitejs/plugin-react@4.3.4': + resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + + '@vitest/coverage-v8@3.0.5': + resolution: {integrity: sha512-zOOWIsj5fHh3jjGwQg+P+J1FW3s4jBu1Zqga0qW60yutsBtqEqNEJKWYh7cYn1yGD+1bdPsPdC/eL4eVK56xMg==} + peerDependencies: + '@vitest/browser': 3.0.5 + vitest: 3.0.5 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/expect@1.6.0': resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + '@vitest/expect@3.0.5': + resolution: {integrity: sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==} + + '@vitest/mocker@3.0.5': + resolution: {integrity: sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.0.5': + resolution: {integrity: sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==} + '@vitest/runner@1.6.0': resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + '@vitest/runner@3.0.5': + resolution: {integrity: sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==} + '@vitest/snapshot@1.6.0': resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + '@vitest/snapshot@3.0.5': + resolution: {integrity: sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==} + '@vitest/spy@1.6.0': resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + '@vitest/spy@3.0.5': + resolution: {integrity: sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==} + '@vitest/utils@1.6.0': resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + '@vitest/utils@3.0.5': + resolution: {integrity: sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==} + '@vue/compiler-core@3.4.32': resolution: {integrity: sha512-8tCVWkkLe/QCWIsrIvExUGnhYCAOroUs5dzhSoKL5w4MJS8uIYiou+pOPSVIOALOQ80B0jBs+Ri+kd5+MBnCDw==} @@ -3875,6 +4091,10 @@ packages: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + engines: {node: '>= 14'} + agentkeepalive@4.5.0: resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} engines: {node: '>= 8.0.0'} @@ -3994,6 +4214,9 @@ packages: aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -4045,6 +4268,10 @@ packages: assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -4191,6 +4418,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + bs-logger@0.2.6: resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} engines: {node: '>= 6'} @@ -4281,6 +4513,9 @@ packages: caniuse-lite@1.0.30001703: resolution: {integrity: sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==} + caniuse-lite@1.0.30001698: + resolution: {integrity: sha512-xJ3km2oiG/MbNU8G6zIq6XRZ6HtAOVXsbOrP/blGazi52kc5Yy7b6sDA5O+FbROzRrV7BSTllLHuNvmawYUJjw==} + canvas@2.11.2: resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==} engines: {node: '>=6'} @@ -4292,6 +4527,10 @@ packages: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} engines: {node: '>=4'} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -4339,6 +4578,10 @@ packages: check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -4647,6 +4890,10 @@ packages: resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} engines: {node: '>=8.0.0'} + cssstyle@4.2.1: + resolution: {integrity: sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==} + engines: {node: '>=18'} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -4804,6 +5051,10 @@ packages: damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + data-view-buffer@1.0.1: resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} engines: {node: '>= 0.4'} @@ -4869,6 +5120,15 @@ packages: supports-color: optional: true + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} @@ -4876,6 +5136,9 @@ packages: decimal.js-light@2.5.1: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} @@ -4919,6 +5182,10 @@ packages: resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} engines: {node: '>=6'} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} @@ -5025,6 +5292,9 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} @@ -5092,6 +5362,9 @@ packages: electron-to-chromium@1.4.829: resolution: {integrity: sha512-5qp1N2POAfW0u1qGAxXEtz6P7bO1m6gpZr5hdf5ve6lxpLM7MpiM4jIPz7xcrNlClQMafbyUDDWjlIQZ1Mw0Rw==} + electron-to-chromium@1.5.96: + resolution: {integrity: sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==} + elkjs@0.9.3: resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} @@ -5169,6 +5442,9 @@ packages: es-module-lexer@1.5.4: resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + es-object-atoms@1.0.0: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} @@ -5202,6 +5478,10 @@ packages: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -5383,6 +5663,10 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5753,6 +6037,9 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} @@ -5853,6 +6140,10 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + html-entities@2.5.2: resolution: {integrity: sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==} @@ -5887,6 +6178,10 @@ packages: resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} engines: {node: '>= 14'} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -6157,6 +6452,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-property@1.0.2: resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} @@ -6265,6 +6563,10 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + istanbul-reports@3.1.7: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} @@ -6455,8 +6757,22 @@ packages: resolution: {integrity: sha512-Jbygqaa20I+0ImPjmMbrsY3QrMkfwfI5G/VNlb6c9nDIyyOw8msfWHzTy04/sawa4rjn0t9WYy3nahWlSjB5zw==} engines: {node: '>=0.1.90'} +<<<<<<< HEAD jsep@1.4.0: resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} +======= + jsdom@26.0.0: + resolution: {integrity: sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + + jsep@1.3.9: + resolution: {integrity: sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==} +>>>>>>> 80a0b9296 (chore: vitest) engines: {node: '>= 10.16.0'} jsesc@0.5.0: @@ -6468,6 +6784,11 @@ packages: engines: {node: '>=4'} hasBin: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -6712,6 +7033,9 @@ packages: loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + lowlight@1.20.0: resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} @@ -6737,13 +7061,23 @@ packages: resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==} engines: {node: '>=12'} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.8: resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} engines: {node: '>=12'} + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + make-dir@1.3.0: resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} engines: {node: '>=4'} @@ -7160,6 +7494,10 @@ packages: resolution: {integrity: sha512-eib56lLOWiJneikoLJE0R0mfnVcKD6wYiEuUNc5bxdhKQZRyPGy6SDp8tVCoJNJdxAgCjlUIurhaq1NtUIHe1A==} engines: {node: '>=16.20.1'} + mongodb-memory-server-core@10.1.3: + resolution: {integrity: sha512-ayBQHeV74wRHhgcAKpxHYI4th9Ufidy/m3XhJnLFRufKsOyDsyHYU3Zxv5Fm4hxsWE6wVd0GAVcQ7t7XNkivOg==} + engines: {node: '>=16.20.1'} + mongodb-memory-server-core@9.2.0: resolution: {integrity: sha512-9SWZEy+dGj5Fvm5RY/mtqHZKS64o4heDwReD4SsfR7+uNgtYo+JN41kPCcJeIH3aJf04j25i5Dia2s52KmsMPA==} engines: {node: '>=14.20.1'} @@ -7168,6 +7506,10 @@ packages: resolution: {integrity: sha512-muyyvITwY3MIfzOedskcO5LJeZs+JBt/T5q5beeXWuXEsMED8o1AGMXzbv2Y2mrmXQscbYnJ1aNXIOfV54HPPQ==} engines: {node: '>=16.20.1'} + mongodb-memory-server@10.1.3: + resolution: {integrity: sha512-QCUjsIIXSYv/EgkpDAjfhlqRKo6N+qR6DD43q4lyrCVn24xQmvlArdWHW/Um5RS4LkC9YWC3XveSncJqht2Hbg==} + engines: {node: '>=16.20.1'} + mongodb-memory-server@9.2.0: resolution: {integrity: sha512-w/usKdYtby5EALERxmA0+et+D0brP0InH3a26shNDgGefXA61hgl6U0P3IfwqZlEGRZdkbZig3n57AHZgDiwvg==} engines: {node: '>=14.20.1'} @@ -7410,6 +7752,9 @@ packages: node-releases@2.0.17: resolution: {integrity: sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-xlsx@0.24.0: resolution: {integrity: sha512-1olwK48XK9nXZsyH/FCltvGrQYvXXZuxVitxXXv2GIuRm51aBi1+5KwR4rWM4KeO61sFU+00913WLZTD+AcXEg==} engines: {node: '>=10.0.0'} @@ -7450,6 +7795,9 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nwsapi@2.2.16: + resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -7605,6 +7953,9 @@ packages: parse5@7.2.0: resolution: {integrity: sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==} + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -7652,9 +8003,16 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathe@2.0.2: + resolution: {integrity: sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==} + pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + pdfjs-dist@4.4.168: resolution: {integrity: sha512-MbkAjpwka/dMHaCfQ75RY1FXX3IewBVu6NGZOcxerRFlaBiIkZmUoR0jotX5VUzYZEXAGzSFtknWs5xRKliXPA==} engines: {node: '>=18'} @@ -7838,6 +8196,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -8035,6 +8397,10 @@ packages: react-native: optional: true + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + react-remove-scroll-bar@2.3.6: resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} engines: {node: '>=10'} @@ -8279,6 +8645,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -8336,6 +8705,10 @@ packages: sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -8536,6 +8909,9 @@ packages: std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} @@ -8701,6 +9077,9 @@ packages: resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} engines: {node: '>=0.10'} + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -8756,6 +9135,10 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + text-decoder@1.1.1: resolution: {integrity: sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==} @@ -8783,14 +9166,39 @@ packages: tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinypool@0.8.4: resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + tinyspy@2.2.1: resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} engines: {node: '>=14.0.0'} + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tldts-core@6.1.76: + resolution: {integrity: sha512-uzhJ02RaMzgQR3yPoeE65DrcHI6LoM4saUqXOt/b5hmb3+mc4YWpdSeAQqVqRUlQ14q8ZuLRWyBR1ictK1dzzg==} + + tldts@6.1.76: + resolution: {integrity: sha512-6U2ti64/nppsDxQs9hw8ephA3nO6nSQvVVfxwRw8wLQPFtLI1cFI1a1eP22g+LUP+1TA2pKKjUTwWB+K2coqmQ==} + hasBin: true + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -8824,6 +9232,10 @@ packages: resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==} engines: {node: '>=14.16'} + tough-cookie@5.1.1: + resolution: {integrity: sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA==} + engines: {node: '>=16'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -8835,6 +9247,10 @@ packages: resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} engines: {node: '>=14'} + tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + engines: {node: '>=18'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -8914,6 +9330,16 @@ packages: '@swc/wasm': optional: true + tsconfck@3.1.5: + resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + tsconfig-paths-webpack-plugin@4.1.0: resolution: {integrity: sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==} engines: {node: '>=10.13.0'} @@ -9118,6 +9544,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.1.2: + resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -9249,6 +9681,19 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true + vite-node@3.0.5: + resolution: {integrity: sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-tsconfig-paths@5.1.4: + resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + vite@5.3.4: resolution: {integrity: sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -9277,6 +9722,9 @@ packages: terser: optional: true + vitest-mongodb@1.0.1: + resolution: {integrity: sha512-a9Mc2F35h8qxI1uOgsrCUH28TglClAd8gdXkn7CBqmC6bLr6D2Ibyxp0Xz6/AU0ukAOfuf/6oqUS+ZN0VlxVyQ==} + vitest@1.6.0: resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -9302,6 +9750,34 @@ packages: jsdom: optional: true + vitest@3.0.5: + resolution: {integrity: sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.0.5 + '@vitest/ui': 3.0.5 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + void-elements@3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} @@ -9314,6 +9790,10 @@ packages: typescript: optional: true + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -9359,6 +9839,14 @@ packages: webpack-cli: optional: true + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + whatwg-url@11.0.0: resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} engines: {node: '>=12'} @@ -9367,6 +9855,10 @@ packages: resolution: {integrity: sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==} engines: {node: '>=16'} + whatwg-url@14.1.0: + resolution: {integrity: sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==} + engines: {node: '>=18'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -9441,16 +9933,35 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xlsx@https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz: resolution: {tarball: https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz} version: 0.20.2 engines: {node: '>=0.8'} hasBin: true + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + xmlbuilder@10.1.1: resolution: {integrity: sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==} engines: {node: '>=4.0'} + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -9603,6 +10114,14 @@ snapshots: call-me-maybe: 1.0.2 openapi-types: 12.1.3 + '@asamuzakjp/css-color@2.8.3': + dependencies: + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + lru-cache: 10.4.3 + '@azure/abort-controller@2.1.2': dependencies: tslib: 2.8.1 @@ -9737,9 +10256,20 @@ snapshots: dependencies: '@babel/highlight': 7.24.7 picocolors: 1.1.1 +<<<<<<< HEAD +======= + + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 +>>>>>>> 80a0b9296 (chore: vitest) '@babel/compat-data@7.24.9': {} + '@babel/compat-data@7.26.8': {} + '@babel/core@7.24.9': dependencies: '@ampproject/remapping': 2.3.0 @@ -9753,6 +10283,27 @@ snapshots: '@babel/traverse': 7.25.6 '@babel/types': 7.25.6 convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.26.8': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.8 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.8) + '@babel/helpers': 7.26.7 + '@babel/parser': 7.26.8 + '@babel/template': 7.26.8 + '@babel/traverse': 7.26.8 + '@babel/types': 7.26.8 + '@types/gensync': 1.0.4 + convert-source-map: 2.0.0 debug: 4.3.7 gensync: 1.0.0-beta.2 json5: 2.2.3 @@ -9774,6 +10325,14 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 + '@babel/generator@7.26.8': + dependencies: + '@babel/parser': 7.26.8 + '@babel/types': 7.26.8 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.24.7': dependencies: '@babel/types': 7.25.6 @@ -9793,6 +10352,14 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-compilation-targets@7.26.5': + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + '@babel/helper-create-class-features-plugin@7.24.8(@babel/core@7.24.9)': dependencies: '@babel/core': 7.24.9 @@ -9820,7 +10387,7 @@ snapshots: '@babel/core': 7.24.9 '@babel/helper-compilation-targets': 7.24.8 '@babel/helper-plugin-utils': 7.24.8 - debug: 4.3.7 + debug: 4.4.0 lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -9853,6 +10420,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.26.8 + '@babel/types': 7.26.8 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.24.9(@babel/core@7.24.9)': dependencies: '@babel/core': 7.24.9 @@ -9864,12 +10438,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.8)': + dependencies: + '@babel/core': 7.26.8 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.8 + transitivePeerDependencies: + - supports-color + '@babel/helper-optimise-call-expression@7.24.7': dependencies: '@babel/types': 7.24.9 '@babel/helper-plugin-utils@7.24.8': {} + '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-remap-async-to-generator@7.24.7(@babel/core@7.24.9)': dependencies: '@babel/core': 7.24.9 @@ -9908,10 +10493,16 @@ snapshots: '@babel/helper-string-parser@7.24.8': {} + '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-option@7.24.8': {} + '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-wrap-function@7.24.7': dependencies: '@babel/helper-function-name': 7.24.7 @@ -9923,9 +10514,14 @@ snapshots: '@babel/helpers@7.24.8': dependencies: - '@babel/template': 7.24.7 + '@babel/template': 7.25.0 '@babel/types': 7.25.6 + '@babel/helpers@7.26.7': + dependencies: + '@babel/template': 7.26.8 + '@babel/types': 7.26.8 + '@babel/highlight@7.24.7': dependencies: '@babel/helper-validator-identifier': 7.24.7 @@ -9941,6 +10537,10 @@ snapshots: dependencies: '@babel/types': 7.25.6 + '@babel/parser@7.26.8': + dependencies: + '@babel/types': 7.26.8 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7(@babel/core@7.24.9)': dependencies: '@babel/core': 7.24.9 @@ -10355,6 +10955,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.8)': + dependencies: + '@babel/core': 7.26.8 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.8)': + dependencies: + '@babel/core': 7.26.8 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-transform-react-jsx@7.24.7(@babel/core@7.24.9)': dependencies: '@babel/core': 7.24.9 @@ -10583,6 +11193,12 @@ snapshots: '@babel/parser': 7.25.6 '@babel/types': 7.25.6 + '@babel/template@7.26.8': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.8 + '@babel/types': 7.26.8 + '@babel/traverse@7.24.8': dependencies: '@babel/code-frame': 7.24.7 @@ -10593,7 +11209,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.7 '@babel/parser': 7.24.8 '@babel/types': 7.24.9 - debug: 4.3.7 + debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -10605,6 +11221,18 @@ snapshots: '@babel/parser': 7.25.6 '@babel/template': 7.25.0 '@babel/types': 7.25.6 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.26.8': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.8 + '@babel/parser': 7.26.8 + '@babel/template': 7.26.8 + '@babel/types': 7.26.8 debug: 4.3.7 globals: 11.12.0 transitivePeerDependencies: @@ -10622,12 +11250,19 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + '@babel/types@7.26.8': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@bany/curl-to-json@1.2.8': dependencies: minimist: 1.2.8 '@bcoe/v8-coverage@0.2.3': {} + '@bcoe/v8-coverage@1.0.2': {} + '@braintree/sanitize-url@6.0.4': {} '@chakra-ui/accordion@2.3.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': @@ -11364,6 +11999,26 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@csstools/color-helpers@5.0.1': {} + + '@csstools/css-calc@2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + + '@csstools/css-color-parser@3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/color-helpers': 5.0.1 + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + + '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/css-tokenizer': 3.0.3 + + '@csstools/css-tokenizer@3.0.3': {} + '@dabh/diagnostics@2.0.3': dependencies: colorspace: 1.1.4 @@ -11389,7 +12044,7 @@ snapshots: '@emotion/babel-plugin@11.11.0': dependencies: '@babel/helper-module-imports': 7.24.7 - '@babel/runtime': 7.24.8 + '@babel/runtime': 7.25.7 '@emotion/hash': 0.9.1 '@emotion/memoize': 0.8.1 '@emotion/serialize': 1.1.4 @@ -11622,7 +12277,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.5 + debug: 4.3.7 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.1 @@ -11710,7 +12365,7 @@ snapshots: '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.5 + debug: 4.3.7 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -12661,6 +13316,27 @@ snapshots: '@tediousjs/connection-string@0.5.0': {} + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/runtime': 7.25.7 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/react@16.2.0(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.7 + '@testing-library/dom': 10.4.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.1 + '@types/react-dom': 18.3.0 + '@tokenizer/token@0.3.0': {} '@trysound/sax@0.2.0': {} @@ -12678,10 +13354,12 @@ snapshots: tslib: 2.8.1 optional: true + '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.24.8 - '@babel/types': 7.24.9 + '@babel/parser': 7.25.6 + '@babel/types': 7.25.6 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 @@ -12692,12 +13370,12 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.24.8 - '@babel/types': 7.24.9 + '@babel/parser': 7.25.6 + '@babel/types': 7.25.6 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.24.9 + '@babel/types': 7.25.6 '@types/body-parser@1.19.5': dependencies: @@ -12873,6 +13551,8 @@ snapshots: dependencies: '@types/node': 20.14.11 + '@types/gensync@1.0.4': {} + '@types/geojson@7946.0.14': {} '@types/graceful-fs@4.1.9': @@ -12957,8 +13637,13 @@ snapshots: '@types/node-fetch@2.6.11': dependencies: +<<<<<<< HEAD '@types/node': 20.14.0 form-data: 4.0.2 +======= + '@types/node': 20.14.11 + form-data: 4.0.1 +>>>>>>> 80a0b9296 (chore: vitest) '@types/node@18.19.40': dependencies: @@ -13137,7 +13822,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.5.3) '@typescript-eslint/utils': 6.21.0(eslint@8.56.0)(typescript@5.5.3) - debug: 4.3.5 + debug: 4.3.7 eslint: 8.56.0 ts-api-utils: 1.3.0(typescript@5.5.3) optionalDependencies: @@ -13183,28 +13868,91 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@vitejs/plugin-react@4.3.4(vite@5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3))': + dependencies: + '@babel/core': 7.26.8 + '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.8) + '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.8) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3) + transitivePeerDependencies: + - supports-color + + '@vitest/coverage-v8@3.0.5(vitest@3.0.5(@types/debug@4.1.12)(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 1.0.2 + debug: 4.4.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + std-env: 3.8.0 + test-exclude: 7.0.1 + tinyrainbow: 2.0.0 + vitest: 3.0.5(@types/debug@4.1.12)(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3) + transitivePeerDependencies: + - supports-color + '@vitest/expect@1.6.0': dependencies: '@vitest/spy': 1.6.0 '@vitest/utils': 1.6.0 chai: 4.4.1 + '@vitest/expect@3.0.5': + dependencies: + '@vitest/spy': 3.0.5 + '@vitest/utils': 3.0.5 + chai: 5.1.2 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.0.5(vite@5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3))': + dependencies: + '@vitest/spy': 3.0.5 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3) + + '@vitest/pretty-format@3.0.5': + dependencies: + tinyrainbow: 2.0.0 + '@vitest/runner@1.6.0': dependencies: '@vitest/utils': 1.6.0 p-limit: 5.0.0 pathe: 1.1.2 + '@vitest/runner@3.0.5': + dependencies: + '@vitest/utils': 3.0.5 + pathe: 2.0.2 + '@vitest/snapshot@1.6.0': dependencies: - magic-string: 0.30.10 + magic-string: 0.30.17 pathe: 1.1.2 pretty-format: 29.7.0 + '@vitest/snapshot@3.0.5': + dependencies: + '@vitest/pretty-format': 3.0.5 + magic-string: 0.30.17 + pathe: 2.0.2 + '@vitest/spy@1.6.0': dependencies: tinyspy: 2.2.1 + '@vitest/spy@3.0.5': + dependencies: + tinyspy: 3.0.2 + '@vitest/utils@1.6.0': dependencies: diff-sequences: 29.6.3 @@ -13212,6 +13960,12 @@ snapshots: loupe: 2.3.7 pretty-format: 29.7.0 + '@vitest/utils@3.0.5': + dependencies: + '@vitest/pretty-format': 3.0.5 + loupe: 3.1.3 + tinyrainbow: 2.0.0 + '@vue/compiler-core@3.4.32': dependencies: '@babel/parser': 7.24.8 @@ -13233,9 +13987,15 @@ snapshots: '@vue/compiler-ssr': 3.4.32 '@vue/shared': 3.4.32 estree-walker: 2.0.2 +<<<<<<< HEAD magic-string: 0.30.10 postcss: 8.5.3 source-map-js: 1.2.1 +======= + magic-string: 0.30.17 + postcss: 8.4.39 + source-map-js: 1.2.0 +>>>>>>> 80a0b9296 (chore: vitest) '@vue/compiler-ssr@3.4.32': dependencies: @@ -13399,17 +14159,19 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color optional: true agent-base@7.1.1: dependencies: - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color + agent-base@7.1.3: {} + agentkeepalive@4.5.0: dependencies: humanize-ms: 1.2.1 @@ -13531,6 +14293,10 @@ snapshots: dependencies: deep-equal: 2.2.3 + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 @@ -13613,6 +14379,8 @@ snapshots: assertion-error@1.1.0: {} + assertion-error@2.0.1: {} + ast-types-flow@0.0.8: {} async-mutex@0.4.1: @@ -13646,8 +14414,13 @@ snapshots: axios@1.8.2: dependencies: +<<<<<<< HEAD follow-redirects: 1.15.9(debug@4.3.7) form-data: 4.0.2 +======= + follow-redirects: 1.15.9(debug@4.4.0) + form-data: 4.0.1 +>>>>>>> 80a0b9296 (chore: vitest) proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -13683,14 +14456,14 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.24.7 - '@babel/types': 7.24.9 + '@babel/template': 7.25.0 + '@babel/types': 7.25.6 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.24.8 + '@babel/runtime': 7.25.7 cosmiconfig: 7.1.0 resolve: 1.22.8 @@ -13814,6 +14587,13 @@ snapshots: node-releases: 2.0.17 update-browserslist-db: 1.1.0(browserslist@4.23.2) + browserslist@4.24.4: + dependencies: + caniuse-lite: 1.0.30001698 + electron-to-chromium: 1.5.96 + node-releases: 2.0.19 + update-browserslist-db: 1.1.2(browserslist@4.24.4) + bs-logger@0.2.6: dependencies: fast-json-stable-stringify: 2.1.0 @@ -13901,6 +14681,8 @@ snapshots: caniuse-lite@1.0.30001703: {} + caniuse-lite@1.0.30001698: {} + canvas@2.11.2(encoding@0.1.13): dependencies: '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) @@ -13923,6 +14705,14 @@ snapshots: pathval: 1.1.1 type-detect: 4.0.8 + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -13963,6 +14753,8 @@ snapshots: dependencies: get-func-name: 2.0.2 + check-error@2.1.1: {} + cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -14286,6 +15078,11 @@ snapshots: dependencies: css-tree: 1.1.3 + cssstyle@4.2.1: + dependencies: + '@asamuzakjp/css-color': 2.8.3 + rrweb-cssom: 0.8.0 + csstype@3.1.3: {} cytoscape-cose-bilkent@4.1.0(cytoscape@3.30.0): @@ -14469,6 +15266,11 @@ snapshots: damerau-levenshtein@1.0.8: {} + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.1.0 + data-view-buffer@1.0.1: dependencies: call-bind: 1.0.7 @@ -14515,10 +15317,16 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.0: + dependencies: + ms: 2.1.3 + decamelize@1.2.0: {} decimal.js-light@2.5.1: {} + decimal.js@10.5.0: {} + decode-named-character-reference@1.0.2: dependencies: character-entities: 2.0.2 @@ -14578,6 +15386,8 @@ snapshots: dependencies: type-detect: 4.0.8 + deep-eql@5.0.2: {} + deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.1 @@ -14679,6 +15489,8 @@ snapshots: dependencies: esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} + dom-helpers@5.2.1: dependencies: '@babel/runtime': 7.25.7 @@ -14762,6 +15574,8 @@ snapshots: electron-to-chromium@1.4.829: {} + electron-to-chromium@1.5.96: {} + elkjs@0.9.3: {} emittery@0.13.1: {} @@ -14889,6 +15703,8 @@ snapshots: es-module-lexer@1.5.4: {} + es-module-lexer@1.6.0: {} + es-object-atoms@1.0.0: dependencies: es-errors: 1.3.0 @@ -14967,6 +15783,8 @@ snapshots: escalade@3.1.2: {} + escalade@3.2.0: {} + escape-html@1.0.3: {} escape-string-regexp@1.0.5: {} @@ -15005,10 +15823,18 @@ snapshots: eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint@8.56.0): dependencies: - debug: 4.3.7 + debug: 4.4.0 enhanced-resolve: 5.17.0 eslint: 8.56.0 +<<<<<<< HEAD eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) +======= +<<<<<<< HEAD + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) +======= + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) +>>>>>>> c2222dcc1 (chore: vitest) +>>>>>>> 80a0b9296 (chore: vitest) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 @@ -15240,6 +16066,8 @@ snapshots: expand-template@2.0.3: {} + expect-type@1.1.0: {} + expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -15477,9 +16305,9 @@ snapshots: dependencies: tslib: 2.8.1 - follow-redirects@1.15.9(debug@4.3.7): + follow-redirects@1.15.9(debug@4.4.0): optionalDependencies: - debug: 4.3.7 + debug: 4.4.0 for-each@0.3.3: dependencies: @@ -15732,6 +16560,8 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + globrex@0.1.2: {} + gopd@1.0.1: dependencies: get-intrinsic: 1.3.0 @@ -15869,6 +16699,10 @@ snapshots: dependencies: react-is: 16.13.1 + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + html-entities@2.5.2: {} html-escaper@2.0.2: {} @@ -15899,14 +16733,14 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color optional: true @@ -15914,7 +16748,14 @@ snapshots: https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.1 - debug: 4.3.7 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -16161,6 +17002,8 @@ snapshots: is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} + is-property@1.0.2: {} is-regex@1.1.4: @@ -16234,7 +17077,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.24.9 - '@babel/parser': 7.24.8 + '@babel/parser': 7.25.6 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -16244,7 +17087,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.24.9 - '@babel/parser': 7.24.8 + '@babel/parser': 7.25.6 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 @@ -16259,12 +17102,20 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.7 + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.4.0 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 @@ -16639,12 +17490,46 @@ snapshots: jschardet@3.1.1: {} +<<<<<<< HEAD jsep@1.4.0: {} +======= + jsdom@26.0.0: + dependencies: + cssstyle: 4.2.1 + data-urls: 5.0.0 + decimal.js: 10.5.0 + form-data: 4.0.1 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.16 + parse5: 7.2.1 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.1 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.1.0 + ws: 8.18.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsep@1.3.9: {} +>>>>>>> 80a0b9296 (chore: vitest) jsesc@0.5.0: {} jsesc@2.5.2: {} + jsesc@3.1.0: {} + json-buffer@3.0.1: {} json-parse-even-better-errors@2.3.1: {} @@ -16909,6 +17794,8 @@ snapshots: dependencies: get-func-name: 2.0.2 + loupe@3.1.3: {} + lowlight@1.20.0: dependencies: fault: 1.0.4 @@ -16928,14 +17815,26 @@ snapshots: luxon@3.4.4: {} + lz-string@1.5.0: {} + magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + magic-string@0.30.8: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magicast@0.3.5: + dependencies: + '@babel/parser': 7.26.8 + '@babel/types': 7.26.8 + source-map-js: 1.2.1 + make-dir@1.3.0: dependencies: pify: 3.0.0 @@ -17519,7 +18418,7 @@ snapshots: micromark@3.2.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.7 + debug: 4.4.0 decode-named-character-reference: 1.0.2 micromark-core-commonmark: 1.1.0 micromark-factory-space: 1.1.0 @@ -17541,7 +18440,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.3.7 + debug: 4.4.0 decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.1 @@ -17685,9 +18584,9 @@ snapshots: dependencies: async-mutex: 0.5.0 camelcase: 6.3.0 - debug: 4.3.7 + debug: 4.4.0 find-cache-dir: 3.3.2 - follow-redirects: 1.15.9(debug@4.3.7) + follow-redirects: 1.15.9(debug@4.4.0) https-proxy-agent: 7.0.5 mongodb: 6.9.0(socks@2.8.3) new-find-package-json: 2.0.0 @@ -17705,13 +18604,37 @@ snapshots: - socks - supports-color + mongodb-memory-server-core@10.1.3(socks@2.8.3): + dependencies: + async-mutex: 0.5.0 + camelcase: 6.3.0 + debug: 4.4.0 + find-cache-dir: 3.3.2 + follow-redirects: 1.15.9(debug@4.4.0) + https-proxy-agent: 7.0.6 + mongodb: 6.9.0(socks@2.8.3) + new-find-package-json: 2.0.0 + semver: 7.6.3 + tar-stream: 3.1.7 + tslib: 2.8.0 + yauzl: 3.1.3 + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - gcp-metadata + - kerberos + - mongodb-client-encryption + - snappy + - socks + - supports-color + mongodb-memory-server-core@9.2.0: dependencies: async-mutex: 0.4.1 camelcase: 6.3.0 - debug: 4.3.7 + debug: 4.4.0 find-cache-dir: 3.3.2 - follow-redirects: 1.15.9(debug@4.3.7) + follow-redirects: 1.15.9(debug@4.4.0) https-proxy-agent: 7.0.5 mongodb: 5.9.2 new-find-package-json: 2.0.0 @@ -17741,6 +18664,20 @@ snapshots: - socks - supports-color + mongodb-memory-server@10.1.3(socks@2.8.3): + dependencies: + mongodb-memory-server-core: 10.1.3(socks@2.8.3) + tslib: 2.8.0 + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - gcp-metadata + - kerberos + - mongodb-client-encryption + - snappy + - socks + - supports-color + mongodb-memory-server@9.2.0: dependencies: mongodb-memory-server-core: 9.2.0 @@ -17877,7 +18814,7 @@ snapshots: new-find-package-json@2.0.0: dependencies: - debug: 4.3.7 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -17970,6 +18907,8 @@ snapshots: node-releases@2.0.17: {} + node-releases@2.0.19: {} + node-xlsx@0.24.0: dependencies: xlsx: https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz @@ -18009,6 +18948,8 @@ snapshots: dependencies: boolbase: 1.0.0 + nwsapi@2.2.16: {} + object-assign@4.1.1: {} object-inspect@1.13.2: {} @@ -18206,6 +19147,10 @@ snapshots: dependencies: entities: 4.5.0 + parse5@7.2.1: + dependencies: + entities: 4.5.0 + parseurl@1.3.3: {} path-exists@4.0.0: {} @@ -18236,8 +19181,12 @@ snapshots: pathe@1.1.2: {} + pathe@2.0.2: {} + pathval@1.1.1: {} + pathval@2.0.0: {} + pdfjs-dist@4.4.168(encoding@0.1.13): optionalDependencies: canvas: 2.11.2(encoding@0.1.13) @@ -18364,7 +19313,11 @@ snapshots: postcss@8.5.3: dependencies: +<<<<<<< HEAD nanoid: 3.3.9 +======= + nanoid: 3.3.7 +>>>>>>> 80a0b9296 (chore: vitest) picocolors: 1.1.1 source-map-js: 1.2.1 @@ -18411,6 +19364,12 @@ snapshots: prettier@3.2.4: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 @@ -18616,7 +19575,7 @@ snapshots: react-redux@7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.24.8 + '@babel/runtime': 7.25.7 '@types/react-redux': 7.1.33 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 @@ -18626,6 +19585,8 @@ snapshots: optionalDependencies: react-dom: 18.3.1(react@18.3.1) + react-refresh@0.14.2: {} + react-remove-scroll-bar@2.3.6(@types/react@18.3.1)(react@18.3.1): dependencies: react: 18.3.1 @@ -18756,7 +19717,7 @@ snapshots: redux@4.2.1: dependencies: - '@babel/runtime': 7.24.8 + '@babel/runtime': 7.25.7 reflect-metadata@0.2.2: {} @@ -18981,6 +19942,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.18.1 fsevents: 2.3.3 + rrweb-cssom@0.8.0: {} + run-async@2.4.1: {} run-async@3.0.0: {} @@ -19034,6 +19997,10 @@ snapshots: sax@1.4.1: {} + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -19167,7 +20134,7 @@ snapshots: socks-proxy-agent@8.0.4: dependencies: agent-base: 7.1.1 - debug: 4.3.7 + debug: 4.4.0 socks: 2.8.3 transitivePeerDependencies: - supports-color @@ -19237,6 +20204,8 @@ snapshots: std-env@3.7.0: {} + std-env@3.8.0: {} + stop-iteration-iterator@1.0.0: dependencies: internal-slot: 1.0.7 @@ -19382,7 +20351,7 @@ snapshots: dependencies: component-emitter: 1.3.1 cookiejar: 2.1.4 - debug: 4.3.5 + debug: 4.3.7 fast-safe-stringify: 2.1.1 form-data: 4.0.2 formidable: 2.1.2 @@ -19430,6 +20399,8 @@ snapshots: symbol-observable@4.0.0: {} + symbol-tree@3.2.4: {} + tapable@2.2.1: {} tar-fs@2.1.1: @@ -19511,6 +20482,12 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + text-decoder@1.1.1: dependencies: b4a: 1.6.6 @@ -19533,10 +20510,26 @@ snapshots: tinybench@2.8.0: {} + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + tinypool@0.8.4: {} + tinypool@1.0.2: {} + + tinyrainbow@2.0.0: {} + tinyspy@2.2.1: {} + tinyspy@3.0.2: {} + + tldts-core@6.1.76: {} + + tldts@6.1.76: + dependencies: + tldts-core: 6.1.76 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -19562,6 +20555,10 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 + tough-cookie@5.1.1: + dependencies: + tldts: 6.1.76 + tr46@0.0.3: {} tr46@3.0.0: @@ -19572,6 +20569,10 @@ snapshots: dependencies: punycode: 2.3.1 + tr46@5.0.0: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} trim-lines@3.0.1: {} @@ -19592,7 +20593,7 @@ snapshots: ts-dedent@2.2.0: {} - ts-jest@29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3): + ts-jest@29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0))(typescript@5.5.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -19639,6 +20640,10 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + tsconfck@3.1.5(typescript@5.5.3): + optionalDependencies: + typescript: 5.5.3 + tsconfig-paths-webpack-plugin@4.1.0: dependencies: chalk: 4.1.2 @@ -19869,6 +20874,12 @@ snapshots: escalade: 3.1.2 picocolors: 1.1.1 + update-browserslist-db@1.1.2(browserslist@4.24.4): + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -19999,7 +21010,7 @@ snapshots: vite-node@1.6.0(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3): dependencies: cac: 6.7.14 - debug: 4.3.7 + debug: 4.4.0 pathe: 1.1.2 picocolors: 1.1.1 vite: 5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3) @@ -20013,6 +21024,62 @@ snapshots: - supports-color - terser + vite-node@3.0.5(@types/node@20.14.11)(sass@1.77.8)(terser@5.31.3): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.6.0 + pathe: 2.0.2 + vite: 5.3.4(@types/node@20.14.11)(sass@1.77.8)(terser@5.31.3) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite-node@3.0.5(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.6.0 + pathe: 2.0.2 + vite: 5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite-tsconfig-paths@5.1.4(typescript@5.5.3)(vite@5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3)): + dependencies: + debug: 4.3.7 + globrex: 0.1.2 + tsconfck: 3.1.5(typescript@5.5.3) + optionalDependencies: + vite: 5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3) + transitivePeerDependencies: + - supports-color + - typescript + + vite@5.3.4(@types/node@20.14.11)(sass@1.77.8)(terser@5.31.3): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.39 + rollup: 4.18.1 + optionalDependencies: + '@types/node': 20.14.11 + fsevents: 2.3.3 + sass: 1.77.8 + terser: 5.31.3 + vite@5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3): dependencies: esbuild: 0.21.5 @@ -20024,7 +21091,21 @@ snapshots: sass: 1.77.8 terser: 5.31.3 - vitest@1.6.0(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3): + vitest-mongodb@1.0.1(socks@2.8.3): + dependencies: + debug: 4.4.0 + mongodb-memory-server: 10.1.3(socks@2.8.3) + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - gcp-metadata + - kerberos + - mongodb-client-encryption + - snappy + - socks + - supports-color + + vitest@1.6.0(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3): dependencies: '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 @@ -20048,6 +21129,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.7.8 + jsdom: 26.0.0 transitivePeerDependencies: - less - lightningcss @@ -20057,6 +21139,78 @@ snapshots: - supports-color - terser + vitest@3.0.5(@types/debug@4.1.12)(@types/node@20.14.11)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3): + dependencies: + '@vitest/expect': 3.0.5 + '@vitest/mocker': 3.0.5(vite@5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3)) + '@vitest/pretty-format': 3.0.5 + '@vitest/runner': 3.0.5 + '@vitest/snapshot': 3.0.5 + '@vitest/spy': 3.0.5 + '@vitest/utils': 3.0.5 + chai: 5.1.2 + debug: 4.4.0 + expect-type: 1.1.0 + magic-string: 0.30.17 + pathe: 2.0.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 2.0.0 + vite: 5.3.4(@types/node@20.14.11)(sass@1.77.8)(terser@5.31.3) + vite-node: 3.0.5(@types/node@20.14.11)(sass@1.77.8)(terser@5.31.3) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 20.14.11 + jsdom: 26.0.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - stylus + - sugarss + - supports-color + - terser + + vitest@3.0.5(@types/debug@4.1.12)(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3): + dependencies: + '@vitest/expect': 3.0.5 + '@vitest/mocker': 3.0.5(vite@5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3)) + '@vitest/pretty-format': 3.0.5 + '@vitest/runner': 3.0.5 + '@vitest/snapshot': 3.0.5 + '@vitest/spy': 3.0.5 + '@vitest/utils': 3.0.5 + chai: 5.1.2 + debug: 4.4.0 + expect-type: 1.1.0 + magic-string: 0.30.17 + pathe: 2.0.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 2.0.0 + vite: 5.3.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3) + vite-node: 3.0.5(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 22.7.8 + jsdom: 26.0.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - stylus + - sugarss + - supports-color + - terser + void-elements@3.1.0: {} vue@3.4.32(typescript@5.5.3): @@ -20069,6 +21223,10 @@ snapshots: optionalDependencies: typescript: 5.5.3 + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + walker@1.0.8: dependencies: makeerror: 1.0.12 @@ -20127,6 +21285,12 @@ snapshots: - esbuild - uglify-js + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + whatwg-url@11.0.0: dependencies: tr46: 3.0.0 @@ -20137,6 +21301,11 @@ snapshots: tr46: 4.1.1 webidl-conversions: 7.0.0 + whatwg-url@14.1.0: + dependencies: + tr46: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -20255,10 +21424,16 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 + ws@8.18.0: {} + xlsx@https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz: {} + xml-name-validator@5.0.0: {} + xmlbuilder@10.1.1: {} + xmlchars@2.2.0: {} + xtend@4.0.2: {} y18n@4.0.3: {} @@ -20324,7 +21499,7 @@ snapshots: yocto-queue@1.1.1: {} - zhlint@0.7.4(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3)(typescript@5.5.3): + zhlint@0.7.4(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3)(typescript@5.5.3): dependencies: chalk: 4.1.2 glob: 10.4.5 @@ -20333,7 +21508,7 @@ snapshots: remark-frontmatter: 1.3.3 remark-parse: 7.0.2 unified: 8.4.2 - vitest: 1.6.0(@types/node@22.7.8)(sass@1.77.8)(terser@5.31.3) + vitest: 1.6.0(@types/node@22.7.8)(jsdom@26.0.0)(sass@1.77.8)(terser@5.31.3) vue: 3.4.32(typescript@5.5.3) transitivePeerDependencies: - '@edge-runtime/vm' diff --git a/projects/app/jest.config.js b/projects/app/jest.config.js deleted file mode 100644 index 73aa436ad..000000000 --- a/projects/app/jest.config.js +++ /dev/null @@ -1,179 +0,0 @@ -/** - * For a detailed explanation regarding each configuration property, visit: - * https://jestjs.io/docs/configuration - */ -const esModules = ['nanoid'].join('|'); - -/** @type {import('jest').Config} */ -const config = { - // All imported modules in your tests should be mocked automatically - // automock: false, - - // Stop running tests after `n` failures - // bail: 0, - - // The directory where Jest should store its cached dependency information - // cacheDirectory: "/tmp/jest_rs", - - // Automatically clear mock calls, instances, contexts and results before every test - // clearMocks: false, - - // Indicates whether the coverage information should be collected while executing the test - collectCoverage: true, - - // An array of glob patterns indicating a set of files for which coverage information should be collected - // collectCoverageFrom: undefined, - - // The directory where Jest should output its coverage files - coverageDirectory: './tmp/coverage', - - // An array of regexp pattern strings used to skip coverage collection - coveragePathIgnorePatterns: ['/node_modules/', '/__mocks__/', '/src/test/'], - - // Indicates which provider should be used to instrument code for coverage - // coverageProvider: "babel", - - // A list of reporter names that Jest uses when writing coverage reports - coverageReporters: ['json', 'text', 'lcov', 'clover'], - - // An object that configures minimum threshold enforcement for coverage results - // coverageThreshold: undefined, - - // A path to a custom dependency extractor - // dependencyExtractor: undefined, - - // Make calling deprecated APIs throw helpful error messages - // errorOnDeprecated: false, - - // The default configuration for fake timers - // fakeTimers: { - // "enableGlobally": false - // }, - - // Force coverage collection from ignored files using an array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: undefined, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: undefined, - - // A set of global variables that need to be available in all test environments - // globals: {}, - - // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. - // maxWorkers: "50%", - - // An array of directory names to be searched recursively up from the requiring module's location - moduleDirectories: ['node_modules', 'src'], - - // An array of file extensions your modules use - // moduleFileExtensions: ['js', 'mjs', 'cjs', 'jsx', 'ts', 'tsx', 'json', 'node'], - - // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module - moduleNameMapper: { - '@/(.*)': '/src/$1', - '^nanoid(/(.*)|$)': 'nanoid$1' - }, - - // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], - - // Activates notifications for test results - // notify: false, - - // An enum that specifies notification mode. Requires { notify: true } - // notifyMode: "failure-change", - - // A preset that is used as a base for Jest's configuration - preset: 'ts-jest', - - // Run tests from one or more projects - // projects: undefined, - - // Use this configuration option to add custom reporters to Jest - // reporters: undefined, - - // Automatically reset mock state before every test - // resetMocks: false, - - // Reset the module registry before running each individual test - // resetModules: false, - - // A path to a custom resolver - // resolver: undefined, - - // Automatically restore mock state and implementation before every test - // restoreMocks: false, - - // The root directory that Jest should scan for tests and modules within - // rootDir: undefined, - - // A list of paths to directories that Jest should use to search for files in - // roots: [ - // "" - // ], - - // Allows you to use a custom runner instead of Jest's default test runner - // runner: "jest-runner", - - // The paths to modules that run some code to configure or set up the testing environment before each test - // setupFiles: [], - - // A list of paths to modules that run some code to configure or set up the testing framework before each test - // setupFilesAfterEnv: [], - - // The number of seconds after which a test is considered as slow and reported as such in the results. - // slowTestThreshold: 5, - - // A list of paths to snapshot serializer modules Jest should use for snapshot testing - // snapshotSerializers: [], - - // The test environment that will be used for testing - testEnvironment: 'node', - - // Options that will be passed to the testEnvironment - // testEnvironmentOptions: {}, - - // Adds a location field to test results - // testLocationInResults: false, - - // The glob patterns Jest uses to detect test files - // testMatch: [ - // "**/__tests__/**/*.[jt]s?(x)", - // "**/?(*.)+(spec|test).[tj]s?(x)" - // ], - - // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: ['/node_modules/'], - - // The regexp pattern or array of patterns that Jest uses to detect test files - // testRegex: [], - - // This option allows the use of a custom results processor - // testResultsProcessor: undefined, - - // This option allows use of a custom test runner - // testRunner: "jest-circus/runner", - - // A map from regular expressions to paths to transformers - transform: {}, - - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - transformIgnorePatterns: [`/node_modules/(?!${esModules})`] - - // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them - // unmockedModulePathPatterns: undefined, - - // Indicates whether each individual test should be reported during the run - // verbose: undefined, - - // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode - // watchPathIgnorePatterns: [], - - // Whether to use watchman for file crawling - // watchman: true, -}; - -module.exports = config; diff --git a/projects/app/package.json b/projects/app/package.json index 60aba49b6..354ce0a2e 100644 --- a/projects/app/package.json +++ b/projects/app/package.json @@ -6,8 +6,7 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint", - "test": "jest" + "lint": "next lint" }, "dependencies": { "@chakra-ui/anatomy": "2.2.1", @@ -26,7 +25,6 @@ "@fortaine/fetch-event-source": "^3.0.6", "@node-rs/jieba": "1.10.0", "@tanstack/react-query": "^4.24.10", - "@types/jest": "^29.5.2", "@types/nprogress": "^0.2.0", "ahooks": "^3.7.11", "axios": "^1.8.2", @@ -39,7 +37,6 @@ "hyperdown": "^2.4.29", "i18next": "23.11.5", "immer": "^9.0.19", - "jest": "^29.5.0", "js-yaml": "^4.1.0", "json5": "^2.2.3", "jsondiffpatch": "^0.6.0", @@ -69,13 +66,10 @@ "remark-math": "^6.0.0", "request-ip": "^3.3.0", "sass": "^1.58.3", - "ts-jest": "^29.1.0", "use-context-selector": "^1.4.4", "zustand": "^4.3.5" }, "devDependencies": { - "@faker-js/faker": "^9.0.3", - "@shelf/jest-mongodb": "^4.3.2", "@svgr/webpack": "^6.5.1", "@types/formidable": "^2.0.5", "@types/js-yaml": "^4.0.9", @@ -89,8 +83,6 @@ "@types/request-ip": "^0.0.37", "eslint": "8.56.0", "eslint-config-next": "14.2.3", - "mockingoose": "^2.16.2", - "mongodb-memory-server": "^10.0.0", "nextjs-node-loader": "^1.1.5", "typescript": "^5.1.3" } diff --git a/projects/app/src/pages/api/__mocks__/base.ts b/projects/app/src/pages/api/__mocks__/base.ts deleted file mode 100644 index 2a2df4669..000000000 --- a/projects/app/src/pages/api/__mocks__/base.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { MongoMemoryReplSet } from 'mongodb-memory-server'; -import mongoose from 'mongoose'; -import { parseHeaderCertMock } from '@fastgpt/service/test/utils'; -import { initMockData, root } from './db/init'; -import { faker } from '@faker-js/faker/locale/zh_CN'; - -jest.mock('nanoid', () => { - return { - nanoid: () => {} - }; -}); - -jest.mock('@fastgpt/global/common/string/tools', () => { - return { - hashStr(str: string) { - return str; - }, - getNanoid() { - return faker.string.alphanumeric(12); - } - }; -}); - -jest.mock('@fastgpt/service/common/system/log', () => ({ - addLog: { - log: jest.fn(), - warn: jest.fn((...prop) => { - console.warn(prop); - }), - error: jest.fn((...prop) => { - console.error(prop); - }), - info: jest.fn(), - debug: jest.fn() - } -})); - -jest.setMock( - '@fastgpt/service/support/permission/controller', - (() => { - const origin = jest.requireActual< - typeof import('@fastgpt/service/support/permission/controller') - >('@fastgpt/service/support/permission/controller'); - - return { - ...origin, - parseHeaderCert: parseHeaderCertMock - }; - })() -); - -jest.mock('@/service/middleware/entry', () => { - return { - NextAPI: (...args: any) => { - return async function api(req: any, res: any) { - try { - let response = null; - for (const handler of args) { - response = await handler(req, res); - } - return { - code: 200, - data: response - }; - } catch (error) { - return { - code: 500, - error - }; - } - }; - } - }; -}); - -beforeAll(async () => { - // 新建一个内存数据库,然后让 mongoose 连接这个数据库 - if (!global.mongod || !global.mongodb) { - const replSet = new MongoMemoryReplSet({ - instanceOpts: [ - { - storageEngine: 'wiredTiger' - }, - { - storageEngine: 'wiredTiger' - } - ] - }); - replSet.start(); - await replSet.waitUntilRunning(); - const uri = replSet.getUri(); - // const mongod = await MongoMemoryServer.create({ - // instance: { - // replSet: 'testset' - // } - // }); - // global.mongod = mongod; - global.replSet = replSet; - global.mongodb = mongoose; - - await global.mongodb.connect(uri, { - dbName: 'fastgpt_test', - bufferCommands: true, - maxConnecting: 50, - maxPoolSize: 50, - minPoolSize: 20, - connectTimeoutMS: 60000, - waitQueueTimeoutMS: 60000, - socketTimeoutMS: 60000, - maxIdleTimeMS: 300000, - retryWrites: true, - retryReads: true - }); - - await initMockData(); - console.log(root); - } -}); - -afterAll(async () => { - if (global.mongodb) { - await global.mongodb.disconnect(); - } - if (global.replSet) { - await global.replSet.stop(); - } - if (global.mongod) { - await global.mongod.stop(); - } -}); diff --git a/projects/app/src/pages/api/__mocks__/db/init.ts b/projects/app/src/pages/api/__mocks__/db/init.ts deleted file mode 100644 index 33514c02e..000000000 --- a/projects/app/src/pages/api/__mocks__/db/init.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; -import { MongoApp } from '@fastgpt/service/core/app/schema'; -import { MongoMemberGroupModel } from '@fastgpt/service/support/permission/memberGroup/memberGroupSchema'; -import { MongoUser } from '@fastgpt/service/support/user/schema'; -import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema'; -import { MongoTeam } from '@fastgpt/service/support/user/team/teamSchema'; - -export const root = { - uid: '', - tmbId: '', - teamId: '', - isRoot: true, - appId: '' -}; - -export const initMockData = async () => { - const [rootUser] = await MongoUser.create([ - { - username: 'root', - password: '123456' - } - ]); - root.uid = String(rootUser._id); - const [rootTeam] = await MongoTeam.create([ - { - name: 'root Team' - } - ]); - root.teamId = String(rootTeam._id); - const [rootTmb] = await MongoTeamMember.create([ - { - teamId: rootTeam._id, - name: 'owner', - role: 'owner', - userId: rootUser._id, - status: 'active' - } - ]); - root.tmbId = String(rootTmb._id); - await MongoMemberGroupModel.create([ - { - name: DefaultGroupName, - teamId: rootTeam._id - } - ]); - - const [rootApp] = await MongoApp.create([ - { - name: 'root Test App', - teamId: rootTeam._id, - tmbId: rootTmb._id - } - ]); - - root.appId = String(rootApp._id); -}; diff --git a/projects/app/src/pages/api/__mocks__/demo/demo.test.ts b/projects/app/src/pages/api/__mocks__/demo/demo.test.ts deleted file mode 100644 index 26463a3b1..000000000 --- a/projects/app/src/pages/api/__mocks__/demo/demo.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import '@/pages/api/__mocks__/base'; -import { root } from '@/pages/api/__mocks__/db/init'; -import { getTestRequest } from '@fastgpt/service/test/utils'; -import { AppErrEnum } from '@fastgpt/global/common/error/code/app'; -import handler from './demo'; - -// Import the schema -import { MongoOutLink } from '@fastgpt/service/support/outLink/schema'; - -beforeAll(async () => { - // await MongoOutLink.create({ - // shareId: 'aaa', - // appId: root.appId, - // tmbId: root.tmbId, - // teamId: root.teamId, - // type: 'share', - // name: 'aaa' - // }) -}); - -test('Should return a list of outLink', async () => { - // Mock request - const res = (await handler( - ...getTestRequest({ - query: { - appId: root.appId, - type: 'share' - }, - user: root - }) - )) as any; - - expect(res.code).toBe(200); - expect(res.data.length).toBe(2); -}); - -test('appId is required', async () => { - const res = (await handler( - ...getTestRequest({ - query: { - type: 'share' - }, - user: root - }) - )) as any; - expect(res.code).toBe(500); - expect(res.error).toBe(AppErrEnum.unExist); -}); - -test('if type is not provided, return nothing', async () => { - const res = (await handler( - ...getTestRequest({ - query: { - appId: root.appId - }, - user: root - }) - )) as any; - expect(res.code).toBe(200); - expect(res.data.length).toBe(0); -}); diff --git a/projects/app/src/pages/api/__mocks__/demo/demo.ts b/projects/app/src/pages/api/__mocks__/demo/demo.ts deleted file mode 100644 index d0e2ceb3b..000000000 --- a/projects/app/src/pages/api/__mocks__/demo/demo.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next'; -import { NextAPI } from '@/service/middleware/entry'; - -export type demoQuery = {}; - -export type demoBody = {}; - -export type demoResponse = {}; - -async function handler( - req: ApiRequestProps, - res: ApiResponseType -): Promise { - return {}; -} - -export default NextAPI(handler); diff --git a/projects/app/src/pages/api/__mocks__/type.d.ts b/projects/app/src/pages/api/__mocks__/type.d.ts deleted file mode 100644 index fe65eb341..000000000 --- a/projects/app/src/pages/api/__mocks__/type.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { MongoMemoryReplSet, MongoMemoryServer } from 'mongodb-memory-server'; -declare global { - var mongod: MongoMemoryServer | undefined; - var replSet: MongoMemoryReplSet | undefined; -} - -export type RequestResponse = { - code: number; - error?: string; - data?: T; -}; diff --git a/projects/app/src/pages/api/core/app/version/latest.test.ts b/projects/app/src/pages/api/core/app/version/latest.test.ts deleted file mode 100644 index 326d71312..000000000 --- a/projects/app/src/pages/api/core/app/version/latest.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import '@/pages/api/__mocks__/base'; -import { root } from '@/pages/api/__mocks__/db/init'; -import { getTestRequest } from '@fastgpt/service/test/utils'; -import handler, { getLatestVersionQuery, getLatestVersionResponse } from './latest'; -import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema'; - -beforeAll(async () => { - // 创建3个测试数据,其中2个是已发布的 - await MongoAppVersion.create([ - { - appId: root.appId, - nodes: [1], - edges: [], - chatConfig: {}, - isPublish: false, - versionName: 'v1', - tmbId: root.tmbId, - time: new Date('2023-01-01') - }, - { - appId: root.appId, - nodes: [2], - edges: [], - chatConfig: {}, - isPublish: true, - versionName: 'v2', - tmbId: root.tmbId, - time: new Date('2023-01-02') - }, - { - appId: root.appId, - nodes: [3], - edges: [], - chatConfig: {}, - isPublish: false, - versionName: 'v3', - tmbId: root.tmbId, - time: new Date('2023-01-03') - } - ]); -}); - -test('获取最新版本并检查', async () => { - const _res = (await handler( - ...getTestRequest<{}, getLatestVersionQuery>({ - query: { - appId: root.appId - }, - user: root - }) - )) as any; - const res = _res.data as getLatestVersionResponse; - - expect(res.nodes[0]).toEqual(2); -}); diff --git a/projects/app/src/pages/api/core/app/version/lis.test.ts b/projects/app/src/pages/api/core/app/version/lis.test.ts deleted file mode 100644 index d415bf5ef..000000000 --- a/projects/app/src/pages/api/core/app/version/lis.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -import '@/pages/api/__mocks__/base'; -import { root } from '@/pages/api/__mocks__/db/init'; -import { getTestRequest } from '@fastgpt/service/test/utils'; -import handler, { versionListBody, versionListResponse } from './list'; - -// Import the schema -import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema'; - -const total = 22; - -beforeAll(async () => { - const arr = new Array(total).fill(0); - await MongoAppVersion.insertMany( - arr.map((_, index) => ({ - appId: root.appId, - nodes: [], - edges: [], - chatConfig: {}, - isPublish: index % 2 === 0, - versionName: `v` + index, - tmbId: root.tmbId, - time: new Date(index * 1000) - })) - ); -}); - -test('Get version list and check', async () => { - const offset = 0; - const pageSize = 10; - - const _res = (await handler( - ...getTestRequest<{}, versionListBody>({ - body: { - offset, - pageSize, - appId: root.appId - }, - user: root - }) - )) as any; - const res = _res.data as versionListResponse; - - expect(res.total).toBe(total); - expect(res.list.length).toBe(pageSize); - expect(res.list[0].versionName).toBe('v21'); - expect(res.list[9].versionName).toBe('v12'); -}); - -test('Get version list with offset 20', async () => { - const offset = 20; - const pageSize = 10; - - const _res = (await handler( - ...getTestRequest<{}, versionListBody>({ - body: { - offset, - pageSize, - appId: root.appId - }, - user: root - }) - )) as any; - const res = _res.data as versionListResponse; - - expect(res.total).toBe(total); - expect(res.list.length).toBe(2); - expect(res.list[0].versionName).toBe('v1'); - expect(res.list[1].versionName).toBe('v0'); -}); diff --git a/projects/app/src/pages/api/core/app/version/list.test.ts b/projects/app/src/pages/api/core/app/version/list.test.ts new file mode 100644 index 000000000..759886779 --- /dev/null +++ b/projects/app/src/pages/api/core/app/version/list.test.ts @@ -0,0 +1,35 @@ +import { MongoApp } from '@fastgpt/service/core/app/schema'; +import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema'; +import { getRootUser } from '@test/datas/users'; +import { Call } from '@test/utils/request'; +import { describe, expect, it } from 'vitest'; +import handler, { type versionListBody, type versionListResponse } from './list'; + +describe('app version list test', () => { + it('should return app version list', async () => { + const root = await getRootUser(); + const app = await MongoApp.create({ + name: 'test', + tmbId: root.tmbId, + teamId: root.teamId + }); + await MongoAppVersion.create( + [...Array(10).keys()].map((i) => ({ + tmbId: root.tmbId, + appId: app._id, + versionName: `v${i}` + })) + ); + const res = await Call(handler, { + auth: root, + body: { + pageSize: 10, + offset: 0, + appId: app._id + } + }); + expect(res.code).toBe(200); + expect(res.data.total).toBe(10); + expect(res.data.list.length).toBe(10); + }); +}); diff --git a/projects/app/src/pages/api/core/app/version/publish.test.ts b/projects/app/src/pages/api/core/app/version/publish.test.ts deleted file mode 100644 index 95af5230f..000000000 --- a/projects/app/src/pages/api/core/app/version/publish.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import '@/pages/api/__mocks__/base'; -import { root } from '@/pages/api/__mocks__/db/init'; -import { getTestRequest } from '@fastgpt/service/test/utils'; -import handler from './publish'; -import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema'; -import { PostPublishAppProps } from '@/global/core/app/api'; -import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; - -describe('发布应用版本测试', () => { - test('发布一个未发布的版本', async () => { - const publishData: PostPublishAppProps = { - nodes: [], - edges: [], - chatConfig: {}, - isPublish: false, - versionName: '1' - }; - - await handler( - ...getTestRequest<{ appId: string }, PostPublishAppProps>({ - body: publishData, - query: { appId: root.appId }, - user: root - }) - ); - - // 检查数据库是否插入成功 - const insertedVersion = await MongoAppVersion.countDocuments(); - - console.log(insertedVersion, '==-'); - - // expect(insertedVersion).toBeTruthy(); - // expect(insertedVersion?.isPublish).toBe(false); - // expect(insertedVersion?.versionName).toBe('1'); - }); -}); diff --git a/projects/app/src/pages/api/support/outLink/list.test.ts b/projects/app/src/pages/api/support/outLink/list.test.ts deleted file mode 100644 index 524b98416..000000000 --- a/projects/app/src/pages/api/support/outLink/list.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import '../../__mocks__/base'; -import { root } from '../../__mocks__/db/init'; -import { getTestRequest } from '@fastgpt/service/test/utils'; -import type { OutLinkListQuery } from './list'; -import { AppErrEnum } from '@fastgpt/global/common/error/code/app'; -import handler from './list'; -import { MongoOutLink } from '@fastgpt/service/support/outLink/schema'; - -beforeAll(async () => { - await MongoOutLink.create({ - shareId: 'aaa', - appId: root.appId, - tmbId: root.tmbId, - teamId: root.teamId, - type: 'share', - name: 'aaa' - }); - await MongoOutLink.create({ - shareId: 'bbb', - appId: root.appId, - tmbId: root.tmbId, - teamId: root.teamId, - type: 'share', - name: 'bbb' - }); -}); - -test('Should return a list of outLink', async () => { - const res = (await handler( - ...getTestRequest({ - query: { - appId: root.appId, - type: 'share' - }, - user: root - }) - )) as any; - - expect(res.code).toBe(200); - expect(res.data.length).toBe(2); -}); - -test('appId is required', async () => { - const res = (await handler( - ...getTestRequest({ - query: { - type: 'share' - }, - user: root - }) - )) as any; - expect(res.code).toBe(500); - expect(res.error).toBe(AppErrEnum.unExist); -}); - -test('if type is not provided, return nothing', async () => { - const res = (await handler( - ...getTestRequest({ - query: { - appId: root.appId - }, - user: root - }) - )) as any; - expect(res.code).toBe(200); - expect(res.data.length).toBe(0); -}); diff --git a/projects/app/src/pages/api/support/outLink/update.test.ts b/projects/app/src/pages/api/support/outLink/update.test.ts deleted file mode 100644 index 1f3fc42df..000000000 --- a/projects/app/src/pages/api/support/outLink/update.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import '../../__mocks__/base'; -import { getTestRequest } from '@fastgpt/service/test/utils'; -import handler, { OutLinkUpdateBody, OutLinkUpdateQuery } from './update'; -import { MongoOutLink } from '@fastgpt/service/support/outLink/schema'; -import { CommonErrEnum } from '@fastgpt/global/common/error/code/common'; -import { root } from '../../__mocks__/db/init'; - -beforeAll(async () => { - await MongoOutLink.create({ - shareId: 'aaa', - appId: root.appId, - tmbId: root.tmbId, - teamId: root.teamId, - type: 'share', - name: 'aaa' - }); -}); - -test('Update Outlink', async () => { - const outlink = await MongoOutLink.findOne({ name: 'aaa' }).lean(); - if (!outlink) { - throw new Error('Outlink not found'); - } - - const res = (await handler( - ...getTestRequest({ - body: { - _id: outlink._id, - name: 'changed' - }, - user: root - }) - )) as any; - - console.log(res); - expect(res.code).toBe(200); - - const link = await MongoOutLink.findById(outlink._id).lean(); - expect(link?.name).toBe('changed'); -}); - -test('Did not post _id', async () => { - const res = (await handler( - ...getTestRequest({ - body: { - name: 'changed' - }, - user: root - }) - )) as any; - - expect(res.code).toBe(500); - expect(res.error).toBe(CommonErrEnum.missingParams); -}); diff --git a/projects/app/src/test/workflow/loopTest.json b/projects/app/src/test/workflow/loopTest.json new file mode 100644 index 000000000..6c1735652 --- /dev/null +++ b/projects/app/src/test/workflow/loopTest.json @@ -0,0 +1,358 @@ +{ + "nodes": [ + { + "nodeId": "userGuide", + "name": "common:core.module.template.system_config", + "intro": "common:core.module.template.system_config_info", + "avatar": "core/workflow/template/systemConfig", + "flowNodeType": "userGuide", + "position": { + "x": 220.4077028616387, + "y": -429.3158723159836 + }, + "version": "481", + "inputs": [ + { + "key": "welcomeText", + "renderTypeList": [ + "hidden" + ], + "valueType": "string", + "label": "core.app.Welcome Text", + "value": "" + }, + { + "key": "variables", + "renderTypeList": [ + "hidden" + ], + "valueType": "any", + "label": "core.app.Chat Variable", + "value": [] + }, + { + "key": "questionGuide", + "valueType": "any", + "renderTypeList": [ + "hidden" + ], + "label": "core.app.Question Guide", + "value": { + "open": false + } + }, + { + "key": "tts", + "renderTypeList": [ + "hidden" + ], + "valueType": "any", + "label": "", + "value": { + "type": "web" + } + }, + { + "key": "whisper", + "renderTypeList": [ + "hidden" + ], + "valueType": "any", + "label": "", + "value": { + "open": false, + "autoSend": false, + "autoTTSResponse": false + } + }, + { + "key": "scheduleTrigger", + "renderTypeList": [ + "hidden" + ], + "valueType": "any", + "label": "", + "value": null + } + ], + "outputs": [] + }, + { + "nodeId": "448745", + "name": "common:core.module.template.work_start", + "intro": "", + "avatar": "core/workflow/template/workflowStart", + "flowNodeType": "workflowStart", + "position": { + "x": 773.4174945178407, + "y": -331.3158723159836 + }, + "version": "481", + "inputs": [ + { + "key": "userChatInput", + "renderTypeList": [ + "reference", + "textarea" + ], + "valueType": "string", + "label": "common:core.module.input.label.user question", + "required": true, + "toolDescription": "用户问题", + "debugLabel": "" + } + ], + "outputs": [ + { + "id": "userChatInput", + "key": "userChatInput", + "label": "common:core.module.input.label.user question", + "type": "static", + "valueType": "string", + "description": "" + } + ] + }, + { + "nodeId": "nlv8iMRsvgkA", + "name": "批量执行", + "intro": "输入一个数组,遍历数组并将每一个数组元素作为输入元素,执行工作流。", + "avatar": "core/workflow/template/loop", + "flowNodeType": "loop", + "showStatus": true, + "position": { + "x": 1236, + "y": -593 + }, + "version": "4811", + "inputs": [ + { + "key": "loopInputArray", + "renderTypeList": [ + "reference" + ], + "valueType": "arrayNumber", + "required": true, + "label": "数组", + "value": [ + [ + "VARIABLE_NODE_ID", + "list" + ] + ], + "valueDesc": "", + "description": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "childrenNodeIdList", + "renderTypeList": [ + "hidden" + ], + "valueType": "arrayString", + "label": "", + "value": [ + "tRxC7faEoGuE", + "cGnptXbKAyMN" + ] + }, + { + "key": "nodeWidth", + "renderTypeList": [ + "hidden" + ], + "valueType": "number", + "label": "", + "value": 1246.6404923618281 + }, + { + "key": "nodeHeight", + "renderTypeList": [ + "hidden" + ], + "valueType": "number", + "label": "", + "value": 642.1566957382456 + }, + { + "key": "loopNodeInputHeight", + "renderTypeList": [ + "hidden" + ], + "valueType": "number", + "label": "", + "value": 83, + "valueDesc": "", + "description": "", + "debugLabel": "", + "toolDescription": "" + } + ], + "outputs": [ + { + "id": "loopArray", + "key": "loopArray", + "label": "数组执行结果", + "type": "static", + "valueType": "arrayAny", + "valueDesc": "", + "description": "" + } + ] + }, + { + "nodeId": "tRxC7faEoGuE", + "parentNodeId": "nlv8iMRsvgkA", + "name": "开始", + "avatar": "core/workflow/template/loopStart", + "flowNodeType": "loopStart", + "showStatus": false, + "position": { + "x": 1305.782937883576, + "y": -270.30845154767246 + }, + "version": "4811", + "inputs": [ + { + "key": "loopStartInput", + "renderTypeList": [ + "hidden" + ], + "valueType": "any", + "label": "", + "required": true, + "value": "" + }, + { + "key": "loopStartIndex", + "renderTypeList": [ + "hidden" + ], + "valueType": "number", + "label": "workflow:Array_element_index" + } + ], + "outputs": [ + { + "id": "loopStartIndex", + "key": "loopStartIndex", + "label": "workflow:Array_element_index", + "type": "static", + "valueType": "number" + }, + { + "id": "loopStartInput", + "key": "loopStartInput", + "label": "数组元素", + "type": "static", + "valueType": "number" + } + ] + }, + { + "nodeId": "cGnptXbKAyMN", + "parentNodeId": "nlv8iMRsvgkA", + "name": "结束", + "avatar": "core/workflow/template/loopEnd", + "flowNodeType": "loopEnd", + "showStatus": false, + "position": { + "x": 1929.4234302454042, + "y": 135.8482441905731 + }, + "version": "4811", + "inputs": [ + { + "key": "loopEndInput", + "renderTypeList": [ + "reference" + ], + "valueType": "any", + "label": "", + "required": true, + "value": [] + } + ], + "outputs": [] + }, + { + "nodeId": "zpOBWBxfyUap", + "parentNodeId": "nlv8iMRsvgkA", + "name": "指定回复", + "intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。", + "avatar": "core/workflow/template/reply", + "flowNodeType": "answerNode", + "position": { + "x": 1806.423430245404, + "y": -217.4185397094268 + }, + "version": "481", + "inputs": [ + { + "key": "text", + "renderTypeList": [ + "textarea", + "reference" + ], + "valueType": "any", + "required": true, + "label": "回复的内容", + "description": "可以使用 \\n 来实现连续换行。\n可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容。\n如传入非字符串类型数据将会自动转成字符串", + "placeholder": "common:core.module.input.description.Response content", + "value": "{{$tRxC7faEoGuE.loopStartInput$}}", + "valueDesc": "", + "debugLabel": "", + "toolDescription": "" + } + ], + "outputs": [] + } + ], + "edges": [ + { + "source": "448745", + "target": "nlv8iMRsvgkA", + "sourceHandle": "448745-source-right", + "targetHandle": "nlv8iMRsvgkA-target-left" + }, + { + "source": "tRxC7faEoGuE", + "target": "zpOBWBxfyUap", + "sourceHandle": "tRxC7faEoGuE-source-right", + "targetHandle": "zpOBWBxfyUap-target-left" + } + ], + "chatConfig": { + "variables": [ + { + "id": "04sm7m", + "key": "list", + "label": "list", + "type": "custom", + "description": "", + "required": false, + "valueType": "arrayNumber", + "list": [ + { + "value": "", + "label": "" + } + ], + "defaultValue": "[1,2,3]", + "enums": [ + { + "value": "", + "label": "" + } + ] + } + ], + "_id": "67a8d281b54c01f7bd95c995", + "scheduledTriggerConfig": { + "cronString": "", + "timezone": "Asia/Shanghai", + "defaultPrompt": "" + } + } +} diff --git a/projects/app/src/test/workflow/simple.json b/projects/app/src/test/workflow/simple.json new file mode 100644 index 000000000..ce6c0a33c --- /dev/null +++ b/projects/app/src/test/workflow/simple.json @@ -0,0 +1,319 @@ +{ + "nodes": [ + { + "nodeId": "userGuide", + "name": "系统配置", + "intro": "", + "avatar": "core/workflow/template/systemConfig", + "flowNodeType": "userGuide", + "position": { + "x": 531.2422736065552, + "y": -486.7611729549753 + }, + "version": "481", + "inputs": [], + "outputs": [] + }, + { + "nodeId": "workflowStartNodeId", + "name": "流程开始", + "intro": "", + "avatar": "core/workflow/template/workflowStart", + "flowNodeType": "workflowStart", + "position": { + "x": 531.2422736065552, + "y": 244.69591764653183 + }, + "version": "481", + "inputs": [ + { + "key": "userChatInput", + "renderTypeList": [ + "reference", + "textarea" + ], + "valueType": "string", + "label": "workflow:user_question", + "toolDescription": "用户问题", + "required": true, + "debugLabel": "" + } + ], + "outputs": [ + { + "id": "userChatInput", + "key": "userChatInput", + "label": "common:core.module.input.label.user question", + "type": "static", + "valueType": "string", + "description": "" + }, + { + "id": "userFiles", + "key": "userFiles", + "label": "app:workflow.user_file_input", + "description": "app:workflow.user_file_input_desc", + "type": "static", + "valueType": "arrayString" + } + ] + }, + { + "nodeId": "7BdojPlukIQw", + "name": "AI 对话", + "intro": "AI 大模型对话", + "avatar": "core/workflow/template/aiChat", + "flowNodeType": "chatNode", + "showStatus": true, + "position": { + "x": 1106.3238387960757, + "y": -350.6030674683474 + }, + "version": "4813", + "inputs": [ + { + "key": "model", + "renderTypeList": [ + "settingLLMModel", + "reference" + ], + "label": "", + "valueType": "string", + "value": "deepseek-reasoner", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "temperature", + "renderTypeList": [ + "hidden" + ], + "label": "", + "value": 0, + "valueType": "number", + "min": 0, + "max": 10, + "step": 1, + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "maxToken", + "renderTypeList": [ + "hidden" + ], + "label": "", + "value": 8000, + "valueType": "number", + "min": 100, + "max": 4000, + "step": 50, + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "isResponseAnswerText", + "renderTypeList": [ + "hidden" + ], + "label": "", + "value": true, + "valueType": "boolean", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "aiChatQuoteRole", + "renderTypeList": [ + "hidden" + ], + "label": "", + "valueType": "string", + "value": "system", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "quoteTemplate", + "renderTypeList": [ + "hidden" + ], + "label": "", + "valueType": "string", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "quotePrompt", + "renderTypeList": [ + "hidden" + ], + "label": "", + "valueType": "string", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "aiChatVision", + "renderTypeList": [ + "hidden" + ], + "label": "", + "valueType": "boolean", + "value": true, + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "aiChatReasoning", + "renderTypeList": [ + "hidden" + ], + "label": "", + "valueType": "boolean", + "value": true, + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "systemPrompt", + "renderTypeList": [ + "textarea", + "reference" + ], + "max": 3000, + "valueType": "string", + "label": "core.ai.Prompt", + "description": "core.app.tip.systemPromptTip", + "placeholder": "core.app.tip.chatNodeSystemPromptTip", + "value": "", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "history", + "renderTypeList": [ + "numberInput", + "reference" + ], + "valueType": "chatHistory", + "label": "core.module.input.label.chat history", + "required": true, + "min": 0, + "max": 50, + "value": 6, + "description": "workflow:max_dialog_rounds", + "debugLabel": "", + "toolDescription": "" + }, + { + "key": "quoteQA", + "renderTypeList": [ + "settingDatasetQuotePrompt" + ], + "label": "", + "debugLabel": "知识库引用", + "description": "", + "valueType": "datasetQuote", + "toolDescription": "" + }, + { + "key": "fileUrlList", + "renderTypeList": [ + "reference", + "input" + ], + "label": "app:file_quote_link", + "debugLabel": "文件链接", + "valueType": "arrayString", + "value": [ + [ + "workflowStartNodeId", + "userFiles" + ] + ], + "toolDescription": "" + }, + { + "key": "userChatInput", + "renderTypeList": [ + "reference", + "textarea" + ], + "valueType": "string", + "label": "common:core.module.input.label.user question", + "required": true, + "toolDescription": "用户问题", + "value": [ + "workflowStartNodeId", + "userChatInput" + ], + "debugLabel": "" + } + ], + "outputs": [ + { + "id": "history", + "key": "history", + "required": true, + "label": "common:core.module.output.label.New context", + "description": "将本次回复内容拼接上历史记录,作为新的上下文返回", + "valueType": "chatHistory", + "valueDesc": "{\n obj: System | Human | AI;\n value: string;\n}[]", + "type": "static" + }, + { + "id": "answerText", + "key": "answerText", + "required": true, + "label": "common:core.module.output.label.Ai response content", + "description": "将在 stream 回复完毕后触发", + "valueType": "string", + "type": "static" + } + ] + } + ], + "edges": [ + { + "source": "workflowStartNodeId", + "target": "7BdojPlukIQw", + "sourceHandle": "workflowStartNodeId-source-right", + "targetHandle": "7BdojPlukIQw-target-left" + } + ], + "chatConfig": { + "questionGuide": false, + "ttsConfig": { + "type": "web" + }, + "whisperConfig": { + "open": false, + "autoSend": false, + "autoTTSResponse": false + }, + "scheduledTriggerConfig": { + "cronString": "", + "timezone": "Asia/Shanghai", + "defaultPrompt": "" + }, + "chatInputGuide": { + "open": false, + "textList": [], + "customUrl": "" + }, + "instruction": "", + "autoExecute": { + "open": false, + "defaultPrompt": "" + }, + "welcomeText": "", + "variables": [], + "fileSelectConfig": { + "canSelectFile": false, + "canSelectImg": false, + "maxFiles": 10 + }, + "_id": "66f4c2f5e9e4e93a95141004" + } +} diff --git a/projects/app/src/test/workflow/workflow.test.ts b/projects/app/src/test/workflow/workflow.test.ts new file mode 100644 index 000000000..126656e97 --- /dev/null +++ b/projects/app/src/test/workflow/workflow.test.ts @@ -0,0 +1,82 @@ +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { dispatchWorkFlow } from '@fastgpt/service/core/workflow/dispatch'; +import { + getWorkflowEntryNodeIds, + storeNodes2RuntimeNodes +} from '@fastgpt/global/core/workflow/runtime/utils'; +import { ChatItemValueTypeEnum } from '@fastgpt/global/core/chat/constants'; +vi.mock(import('@fastgpt/service/common/string/tiktoken'), async (importOriginal) => { + const mod = await importOriginal(); + return { + ...mod, + countGptMessagesTokens: async () => { + return 1; + } + }; +}); + +vi.mock(import('@fastgpt/service/support/wallet/usage/utils'), async (importOriginal) => { + const mod = await importOriginal(); + return { + ...mod, + formatModelChars2Points: () => ({ + modelName: 'test', + totalPoints: 1 + }) + }; +}); + +const testWorkflow = async (path: string) => { + const workflowStr = readFileSync(resolve(path), 'utf-8'); + const workflow = JSON.parse(workflowStr); + const { nodes, edges, chatConfig } = workflow; + let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes)); + const variables = {}; + const { assistantResponses, flowResponses } = await dispatchWorkFlow({ + mode: 'test', + runningAppInfo: { + id: 'test', + teamId: 'test', + tmbId: 'test' + }, + runningUserInfo: { + tmbId: 'test', + teamId: 'test' + }, + timezone: 'Asia/Shanghai', + externalProvider: {}, + uid: 'test', + runtimeNodes, + runtimeEdges: edges, + variables, + query: [ + { + type: ChatItemValueTypeEnum.text, + text: { + content: '你是谁' + } + } + ], + chatConfig, + histories: [], + stream: false, + maxRunTimes: 5 + }); + expect(assistantResponses).toBeDefined(); + expect(assistantResponses[0].text?.content).toBeDefined(); + return { + assistantResponses, + flowResponses + }; +}; + +it('Workflow test: simple workflow', async () => { + // create a simple app + await testWorkflow('projects/app/src/test/workflow/simple.json'); +}); + +it('Workflow test: output test', async () => { + console.log(await testWorkflow('projects/app/src/test/workflow/loopTest.json')); +}); diff --git a/projects/app/tsconfig.json b/projects/app/tsconfig.json index 7d58a40e2..9782f2837 100644 --- a/projects/app/tsconfig.json +++ b/projects/app/tsconfig.json @@ -3,8 +3,10 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "@test/*": ["../../test/*"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../../packages/**/*.d.ts"] + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../../packages/**/*.d.ts"], + "exclude": ["**/*.test.ts"] } diff --git a/test/datas/users.ts b/test/datas/users.ts new file mode 100644 index 000000000..05002e052 --- /dev/null +++ b/test/datas/users.ts @@ -0,0 +1,34 @@ +import { AuthUserTypeEnum } from '@fastgpt/global/support/permission/constant'; +import { MongoUser } from '@fastgpt/service/support/user/schema'; +import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema'; +import { MongoTeam } from '@fastgpt/service/support/user/team/teamSchema'; +import { parseHeaderCertRet } from 'test/mocks/request'; + +export async function getRootUser(): Promise { + const rootUser = await MongoUser.create({ + username: 'root', + password: '123456' + }); + + const team = await MongoTeam.create({ + name: 'test team', + ownerId: rootUser._id + }); + + const tmb = await MongoTeamMember.create({ + teamId: team._id, + userId: rootUser._id, + status: 'active' + }); + + return { + userId: rootUser._id, + apikey: '', + appId: '', + authType: AuthUserTypeEnum.token, + isRoot: true, + sourceName: undefined, + teamId: tmb?.teamId, + tmbId: tmb?._id + }; +} diff --git a/test/mocks/index.ts b/test/mocks/index.ts new file mode 100644 index 000000000..0e12cd8ce --- /dev/null +++ b/test/mocks/index.ts @@ -0,0 +1 @@ +import './request'; diff --git a/test/mocks/request.ts b/test/mocks/request.ts new file mode 100644 index 000000000..5a576018a --- /dev/null +++ b/test/mocks/request.ts @@ -0,0 +1,89 @@ +import { AuthUserTypeEnum } from '@fastgpt/global/support/permission/constant'; +import { vi } from 'vitest'; + +// vi.mock(import('@/service/middleware/entry'), async () => { +// const NextAPI = vi.fn((handler: any) => handler); +// return { +// NextAPI +// }; +// }); + +vi.mock(import('@fastgpt/service/common/middle/entry'), async (importOriginal) => { + const mod = await importOriginal(); + const NextEntry = vi.fn(({ beforeCallback = [] }: { beforeCallback?: Promise[] }) => { + return (...args: any) => { + return async function api(req: any, res: any) { + try { + await Promise.all([...beforeCallback]); + let response = null; + for await (const handler of args) { + response = await handler(req, res); + if (res.writableFinished) { + break; + } + } + return { + code: 200, + data: response + }; + } catch (error) { + return { + code: 500, + error, + url: req.url + }; + } + }; + }; + }); + + return { + ...mod, + NextEntry + }; +}); + +export type parseHeaderCertRet = { + userId: string; + teamId: string; + tmbId: string; + appId: string; + authType: AuthUserTypeEnum; + sourceName: string | undefined; + apikey: string; + isRoot: boolean; +}; + +export type MockReqType = { + body?: B; + query?: Q; + auth?: parseHeaderCertRet; + [key: string]: any; +}; + +vi.mock(import('@fastgpt/service/support/permission/controller'), async (importOriginal) => { + const mod = await importOriginal(); + const parseHeaderCert = vi.fn( + ({ + req, + authToken = false, + authRoot = false, + authApiKey = false + }: { + req: MockReqType; + authToken?: boolean; + authRoot?: boolean; + authApiKey?: boolean; + }) => { + const { auth } = req; + if (!auth) { + return Promise.reject(Error('unAuthorization')); + } + return Promise.resolve(auth); + } + ); + return { + ...mod, + parseHeaderCert + }; +}); diff --git a/test/setup.ts b/test/setup.ts new file mode 100644 index 000000000..3d57e6d30 --- /dev/null +++ b/test/setup.ts @@ -0,0 +1,88 @@ +import { existsSync, readFileSync } from 'fs'; +import mongoose from '@fastgpt/service/common/mongo'; +import { connectMongo } from '@fastgpt/service/common/mongo/init'; +import { initGlobalVariables } from '@/service/common/system'; +import { afterAll, beforeAll, vi } from 'vitest'; +import { setup, teardown } from 'vitest-mongodb'; +import setupModels from './setupModels'; +import './mocks'; + +vi.stubEnv('NODE_ENV', 'test'); +vi.mock(import('@fastgpt/service/common/mongo'), async (importOriginal) => { + const mod = await importOriginal(); + return { + ...mod, + connectionMongo: await (async () => { + if (!global.mongodb) { + global.mongodb = mongoose; + await global.mongodb.connect((globalThis as any).__MONGO_URI__ as string); + } + + return global.mongodb; + })() + }; +}); + +vi.mock(import('@/service/common/system'), async (importOriginal) => { + const mod = await importOriginal(); + return { + ...mod, + getSystemVersion: async () => { + return '0.0.0'; + }, + readConfigData: async () => { + return readFileSync('@/data/config.json', 'utf-8'); + }, + initSystemConfig: async () => { + // read env from projects/app/.env + + const str = readFileSync('projects/app/.env.local', 'utf-8'); + const lines = str.split('\n'); + const systemEnv: Record = {}; + for (const line of lines) { + const [key, value] = line.split('='); + if (key && value) { + systemEnv[key] = value; + } + } + global.systemEnv = systemEnv as any; + + return; + } + }; +}); + +beforeAll(async () => { + await setup({ + type: 'replSet', + serverOptions: { + replSet: { + count: 4 + } + } + }); + vi.stubEnv('MONGODB_URI', (globalThis as any).__MONGO_URI__); + initGlobalVariables(); + await connectMongo(); + + // await getInitConfig(); + if (existsSync('projects/app/.env.local')) { + const str = readFileSync('projects/app/.env.local', 'utf-8'); + const lines = str.split('\n'); + const systemEnv: Record = {}; + for (const line of lines) { + const [key, value] = line.split('='); + if (key && value && !key.startsWith('#')) { + systemEnv[key] = value; + } + } + global.systemEnv = {} as any; + global.systemEnv.oneapiUrl = systemEnv['OPENAI_BASE_URL']; + global.systemEnv.chatApiKey = systemEnv['CHAT_API_KEY']; + await setupModels(); + } +}); + +afterAll(async () => { + await teardown(); +}); diff --git a/test/setupModels.ts b/test/setupModels.ts new file mode 100644 index 000000000..4bc02f73b --- /dev/null +++ b/test/setupModels.ts @@ -0,0 +1,52 @@ +import { ModelTypeEnum } from 'packages/global/core/ai/model'; +import { ModelProviderIdType } from 'packages/global/core/ai/provider'; + +export default async function setupModels() { + global.llmModelMap = new Map(); + global.llmModelMap.set('gpt-4o-mini', { + type: ModelTypeEnum.llm, + model: 'gpt-4o-mini', + name: 'gpt-4o-mini', + avatar: 'gpt-4o-mini', + isActive: true, + isDefault: true, + isCustom: false, + requestUrl: undefined, + requestAuth: undefined, + customCQPrompt: '', + customExtractPrompt: '', + defaultSystemChatPrompt: undefined, + fieldMap: undefined, + defaultConfig: undefined, + provider: 'OpenAI' as ModelProviderIdType, + functionCall: false, + toolChoice: false, + maxContext: 4096, + maxResponse: 4096, + quoteMaxToken: 2048 + }); + global.systemDefaultModel = { + llm: { + type: ModelTypeEnum.llm, + model: 'gpt-4o-mini', + name: 'gpt-4o-mini', + avatar: 'gpt-4o-mini', + isActive: true, + isDefault: true, + isCustom: false, + requestUrl: undefined, + requestAuth: undefined, + customCQPrompt: '', + customExtractPrompt: '', + defaultSystemChatPrompt: undefined, + fieldMap: undefined, + defaultConfig: undefined, + provider: 'OpenAI' as ModelProviderIdType, + functionCall: false, + toolChoice: false, + maxContext: 4096, + maxResponse: 4096, + quoteMaxToken: 2048 + } + }; +} diff --git a/test/test.ts b/test/test.ts new file mode 100644 index 000000000..57b67c4ed --- /dev/null +++ b/test/test.ts @@ -0,0 +1,18 @@ +import { MongoUser } from '@fastgpt/service/support/user/schema'; +import { it, expect } from 'vitest'; + +it('should be a test', async () => { + expect(1).toBe(1); +}); + +it('should be able to connect to mongo', async () => { + expect(global.mongodb).toBeDefined(); + expect(global.mongodb?.connection.readyState).toBe(1); + await MongoUser.create({ + username: 'test', + password: '123456' + }); + const user = await MongoUser.findOne({ username: 'test' }); + expect(user).toBeDefined(); + expect(user?.username).toBe('test'); +}); diff --git a/test/utils/request.ts b/test/utils/request.ts new file mode 100644 index 000000000..6e94afa20 --- /dev/null +++ b/test/utils/request.ts @@ -0,0 +1,21 @@ +import { NextApiHandler } from '@fastgpt/service/common/middle/entry'; +import { MockReqType } from '../mocks/request'; + +export async function Call( + handler: NextApiHandler, + props?: MockReqType +) { + const { body = {}, query = {}, ...rest } = props || {}; + return (await handler( + { + body: body, + query: query, + ...(rest as any) + }, + {} as any + )) as Promise<{ + code: number; + data: R; + error?: any; + }>; +} diff --git a/tsconfig.json b/tsconfig.json index 092946c2d..9b4dcca57 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,12 @@ "isolatedModules": true, "jsx": "preserve", "incremental": true, - "baseUrl": "." + "baseUrl": ".", + "paths": { + "@/*": ["projects/app/src/*"], + "@fastgpt/*": ["packages/*"], + "@test": ["test/*"] + } }, "exclude": ["**/node_modules"] } diff --git a/vitest.config.mts b/vitest.config.mts new file mode 100644 index 000000000..0ac361b79 --- /dev/null +++ b/vitest.config.mts @@ -0,0 +1,23 @@ +import { resolve } from 'path'; +import { defineConfig } from 'vitest/config'; +export default defineConfig({ + test: { + coverage: { + enabled: true, + reporter: ['html', 'json-summary', 'json'], + all: false, + reportOnFailure: true + }, + outputFile: 'test-results.json', + setupFiles: ['./test/setup.ts'], + include: ['./test/test.ts', './projects/app/**/*.test.ts'], + testTimeout: 5000 + }, + resolve: { + alias: { + '@': resolve('projects/app/src'), + '@fastgpt': resolve('packages'), + '@test': resolve('test') + } + } +});