From 3fdbfba57bd0ae548cb521b0e348d5e9bd754065 Mon Sep 17 00:00:00 2001 From: Mgrdich <46796009+Mgrdich@users.noreply.github.com> Date: Mon, 15 Apr 2024 17:45:35 +0400 Subject: [PATCH] FE: Packages housekeeping (#265) Co-authored-by: Roman Zabaluev --- frontend/package.json | 21 +- frontend/pnpm-lock.yaml | 683 +++++++++++------- .../ACLPage/Form/CustomACL/Form.tsx | 2 +- .../ACLPage/Form/ForConsumers/Form.tsx | 2 +- .../ACLPage/Form/ForKafkaStreamApps/Form.tsx | 2 +- .../ACLPage/Form/ForProducers/Form.tsx | 2 +- frontend/src/components/ACLPage/List/List.tsx | 2 +- .../Brokers/BrokersList/BrokersList.tsx | 2 +- .../ConsumerGroups/Details/ListItem.tsx | 2 +- .../renderer/TableRenderer/TableRenderer.tsx | 18 +- .../components/Schemas/Details/Details.tsx | 85 +-- .../Schemas/Details/__test__/Details.spec.tsx | 132 ++-- .../Schemas/Details/__test__/fixtures.ts | 2 +- frontend/src/components/Schemas/Diff/Diff.tsx | 28 +- .../components/Schemas/Diff/DiffContainer.ts | 15 - .../Schemas/Diff/__test__/Diff.spec.tsx | 93 +-- frontend/src/components/Schemas/Edit/Edit.tsx | 44 +- frontend/src/components/Schemas/Edit/Form.tsx | 86 +-- .../Schemas/Edit/__tests__/Edit.spec.tsx | 91 ++- .../Schemas/Edit/__tests__}/fixtures.ts | 26 - .../GlobalSchemaSelector.tsx | 72 +- .../__test__/GlobalSchemaSelector.spec.tsx | 65 +- frontend/src/components/Schemas/List/List.tsx | 47 +- .../Schemas/List/__test__/List.spec.tsx | 118 ++- .../Schemas/List/__test__/fixtures.ts | 2 +- frontend/src/components/Schemas/New/New.tsx | 31 +- frontend/src/components/Schemas/Schemas.tsx | 7 +- .../Schemas/__test__/Schemas.spec.tsx | 2 +- .../Topics/List/BatchActionsBar.tsx | 2 +- .../src/components/Topics/List/TopicTable.tsx | 2 +- .../Topics/List/__tests__/TopicTable.spec.tsx | 5 - frontend/src/components/Topics/New/New.tsx | 2 +- .../src/components/Topics/Topic/Edit/Edit.tsx | 2 +- .../Topics/Topic/__test__/Topic.spec.tsx | 10 - .../Form/CustomParams/CustomParamField.tsx | 2 +- .../shared/Form/CustomParams/CustomParams.tsx | 2 +- .../Topics/shared/Form/TopicForm.tsx | 3 +- frontend/src/index.tsx | 14 +- frontend/src/lib/functions/nanoid.ts | 22 + .../lib/hooks/api/__tests__/schema.spec.ts | 148 ++++ .../lib/hooks/api/__tests__/topics.spec.ts | 2 +- frontend/src/lib/hooks/api/acl.ts | 2 +- frontend/src/lib/hooks/api/brokers.ts | 2 +- frontend/src/lib/hooks/api/clusters.ts | 2 +- frontend/src/lib/hooks/api/consumers.ts | 2 +- frontend/src/lib/hooks/api/kafkaConnect.ts | 2 +- frontend/src/lib/hooks/api/ksqlDb.tsx | 2 +- frontend/src/lib/hooks/api/schemas.ts | 177 +++++ frontend/src/lib/hooks/api/topicMessages.tsx | 3 +- frontend/src/lib/hooks/api/topics.ts | 12 +- frontend/src/lib/hooks/redux.ts | 5 - .../src/{redux => lib}/interfaces/cluster.ts | 0 .../src/{redux => lib}/interfaces/schema.ts | 0 .../src/{redux => lib}/interfaces/topic.ts | 16 +- frontend/src/lib/paths.ts | 4 +- frontend/src/lib/queries.ts | 8 + frontend/src/lib/testHelpers.tsx | 26 +- .../src/redux/interfaces/consumerGroup.ts | 18 - frontend/src/redux/interfaces/index.ts | 11 - frontend/src/redux/interfaces/loader.ts | 5 - frontend/src/redux/reducers/index.ts | 8 - .../src/redux/reducers/loader/loaderSlice.ts | 51 -- .../src/redux/reducers/loader/selectors.ts | 5 - .../redux/reducers/schemas/schemasSlice.ts | 147 ---- frontend/src/redux/store/index.ts | 7 - 65 files changed, 1207 insertions(+), 1206 deletions(-) delete mode 100644 frontend/src/components/Schemas/Diff/DiffContainer.ts rename frontend/src/{redux/reducers/schemas/__test__ => components/Schemas/Edit/__tests__}/fixtures.ts (64%) create mode 100644 frontend/src/lib/functions/nanoid.ts create mode 100644 frontend/src/lib/hooks/api/__tests__/schema.spec.ts create mode 100644 frontend/src/lib/hooks/api/schemas.ts delete mode 100644 frontend/src/lib/hooks/redux.ts rename frontend/src/{redux => lib}/interfaces/cluster.ts (100%) rename frontend/src/{redux => lib}/interfaces/schema.ts (100%) rename frontend/src/{redux => lib}/interfaces/topic.ts (76%) create mode 100644 frontend/src/lib/queries.ts delete mode 100644 frontend/src/redux/interfaces/consumerGroup.ts delete mode 100644 frontend/src/redux/interfaces/index.ts delete mode 100644 frontend/src/redux/interfaces/loader.ts delete mode 100644 frontend/src/redux/reducers/index.ts delete mode 100644 frontend/src/redux/reducers/loader/loaderSlice.ts delete mode 100644 frontend/src/redux/reducers/loader/selectors.ts delete mode 100644 frontend/src/redux/reducers/schemas/schemasSlice.ts delete mode 100644 frontend/src/redux/store/index.ts diff --git a/frontend/package.json b/frontend/package.json index 26be7c951..261894014 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,19 +8,13 @@ "@hookform/error-message": "^2.0.0", "@hookform/resolvers": "^2.7.1", "@microsoft/fetch-event-source": "^2.0.1", - "@reduxjs/toolkit": "^1.8.3", "@szhsin/react-menu": "^3.5.3", "@tanstack/react-query": "^4.0.5", "@tanstack/react-table": "^8.5.10", - "@testing-library/react": "^14.0.0", - "@types/testing-library__jest-dom": "^5.14.5", "ace-builds": "^1.7.1", "ajv": "^8.6.3", "ajv-formats": "^2.1.1", "classnames": "^2.2.6", - "fetch-mock": "^9.11.0", - "jest": "^29.4.3", - "jest-watch-typeahead": "^2.2.2", "json-schema-faker": "^0.5.6", "jsonpath-plus": "^7.2.0", "lodash": "^4.17.21", @@ -35,15 +29,10 @@ "react-hot-toast": "^2.4.0", "react-is": "^18.2.0", "react-multi-select-component": "^4.3.3", - "react-redux": "^8.0.2", "react-router-dom": "^6.3.0", - "redux": "^4.2.0", "sass": "^1.52.3", "styled-components": "^5.3.1", "use-debounce": "^9.0.3", - "vite": "^4.5.2", - "vite-tsconfig-paths": "^4.0.2", - "whatwg-fetch": "^3.6.2", "yup": "^1.0.0", "zustand": "^4.1.1" }, @@ -82,6 +71,8 @@ "@types/styled-components": "^5.1.13", "@typescript-eslint/eslint-plugin": "^5.29.0", "@typescript-eslint/parser": "^5.29.0", + "vite": "^4.5.2", + "vite-tsconfig-paths": "^4.0.2", "@vitejs/plugin-react-swc": "^3.0.0", "dotenv": "^16.0.1", "eslint": "^8.3.0", @@ -96,6 +87,10 @@ "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.5.0", + "@testing-library/react": "^14.0.0", + "@types/testing-library__jest-dom": "^5.14.5", + "jest": "^29.4.3", + "jest-watch-typeahead": "^2.2.2", "jest-environment-jsdom": "^29.4.3", "jest-sonar-reporter": "^2.0.0", "jest-styled-components": "^7.1.1", @@ -105,7 +100,9 @@ "ts-prune": "^0.10.3", "typescript": "^4.7.4", "vite-plugin-checker": "^0.6.4", - "vite-plugin-ejs": "^1.6.4" + "vite-plugin-ejs": "^1.6.4", + "fetch-mock": "^9.11.0", + "whatwg-fetch": "^3.6.2" }, "engines": { "node": "v18.17.1", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 1e4006a28..399a902cd 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -28,9 +28,6 @@ dependencies: '@microsoft/fetch-event-source': specifier: ^2.0.1 version: 2.0.1 - '@reduxjs/toolkit': - specifier: ^1.8.3 - version: 1.8.3(react-redux@8.0.2)(react@18.2.0) '@szhsin/react-menu': specifier: ^3.5.3 version: 3.5.3(react-dom@18.1.0)(react@18.2.0) @@ -40,12 +37,6 @@ dependencies: '@tanstack/react-table': specifier: ^8.5.10 version: 8.5.10(react-dom@18.1.0)(react@18.2.0) - '@testing-library/react': - specifier: ^14.0.0 - version: 14.0.0(react-dom@18.1.0)(react@18.2.0) - '@types/testing-library__jest-dom': - specifier: ^5.14.5 - version: 5.14.5 ace-builds: specifier: ^1.7.1 version: 1.7.1 @@ -58,15 +49,6 @@ dependencies: classnames: specifier: ^2.2.6 version: 2.3.1 - fetch-mock: - specifier: ^9.11.0 - version: 9.11.0 - jest: - specifier: ^29.4.3 - version: 29.6.4(@types/node@20.11.17)(ts-node@10.9.1) - jest-watch-typeahead: - specifier: ^2.2.2 - version: 2.2.2(jest@29.6.4) json-schema-faker: specifier: ^0.5.6 version: 0.5.6 @@ -109,15 +91,9 @@ dependencies: react-multi-select-component: specifier: ^4.3.3 version: 4.3.3(react-dom@18.1.0)(react@18.2.0) - react-redux: - specifier: ^8.0.2 - version: 8.0.2(@types/react-dom@18.0.5)(@types/react@18.2.21)(react-dom@18.1.0)(react@18.2.0)(redux@4.2.0) react-router-dom: specifier: ^6.3.0 version: 6.15.0(react-dom@18.1.0)(react@18.2.0) - redux: - specifier: ^4.2.0 - version: 4.2.0 sass: specifier: ^1.52.3 version: 1.66.1 @@ -127,15 +103,6 @@ dependencies: use-debounce: specifier: ^9.0.3 version: 9.0.4(react@18.2.0) - vite: - specifier: ^4.5.2 - version: 4.5.3(@types/node@20.11.17)(sass@1.66.1) - vite-tsconfig-paths: - specifier: ^4.0.2 - version: 4.3.1(typescript@4.7.4)(vite@4.5.3) - whatwg-fetch: - specifier: ^3.6.2 - version: 3.6.2 yup: specifier: ^1.0.0 version: 1.3.3 @@ -162,6 +129,9 @@ devDependencies: '@testing-library/jest-dom': specifier: ^5.16.5 version: 5.16.5 + '@testing-library/react': + specifier: ^14.0.0 + version: 14.0.0(react-dom@18.1.0)(react@18.2.0) '@testing-library/user-event': specifier: ^14.4.3 version: 14.4.3(@testing-library/dom@9.3.1) @@ -192,6 +162,9 @@ devDependencies: '@types/styled-components': specifier: ^5.1.13 version: 5.1.18 + '@types/testing-library__jest-dom': + specifier: ^5.14.5 + version: 5.14.5 '@typescript-eslint/eslint-plugin': specifier: ^5.29.0 version: 5.29.0(@typescript-eslint/parser@5.62.0)(eslint@8.48.0)(typescript@4.7.4) @@ -240,6 +213,12 @@ devDependencies: eslint-plugin-react-hooks: specifier: ^4.5.0 version: 4.6.0(eslint@8.48.0) + fetch-mock: + specifier: ^9.11.0 + version: 9.11.0 + jest: + specifier: ^29.4.3 + version: 29.6.4(@types/node@20.11.17)(ts-node@10.9.1) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.4 @@ -249,6 +228,9 @@ devDependencies: jest-styled-components: specifier: ^7.1.1 version: 7.1.1(styled-components@5.3.1) + jest-watch-typeahead: + specifier: ^2.2.2 + version: 2.2.2(jest@29.6.4) prettier: specifier: ^2.8.4 version: 2.8.4 @@ -264,12 +246,21 @@ devDependencies: typescript: specifier: ^4.7.4 version: 4.7.4 + vite: + specifier: ^4.5.2 + version: 4.5.3(@types/node@20.11.17)(sass@1.66.1) vite-plugin-checker: specifier: ^0.6.4 version: 0.6.4(eslint@8.48.0)(typescript@4.7.4)(vite@4.5.3) vite-plugin-ejs: specifier: ^1.6.4 version: 1.6.4 + vite-tsconfig-paths: + specifier: ^4.0.2 + version: 4.3.1(typescript@4.7.4)(vite@4.5.3) + whatwg-fetch: + specifier: ^3.6.2 + version: 3.6.2 packages: @@ -288,13 +279,14 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.19 - dev: false + dev: true /@babel/code-frame@7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 + dev: true /@babel/code-frame@7.23.5: resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} @@ -306,7 +298,7 @@ packages: /@babel/compat-data@7.18.8: resolution: {integrity: sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==} engines: {node: '>=6.9.0'} - dev: false + dev: true /@babel/core@7.18.2: resolution: {integrity: sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==} @@ -329,7 +321,7 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: false + dev: true /@babel/core@7.18.9: resolution: {integrity: sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==} @@ -352,7 +344,7 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: false + dev: true /@babel/generator@7.18.9: resolution: {integrity: sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==} @@ -361,7 +353,7 @@ packages: '@babel/types': 7.18.9 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 - dev: false + dev: true /@babel/generator@7.23.6: resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} @@ -389,7 +381,7 @@ packages: '@babel/helper-validator-option': 7.18.6 browserslist: 4.20.4 semver: 6.3.1 - dev: false + dev: true /@babel/helper-compilation-targets@7.18.9(@babel/core@7.18.9): resolution: {integrity: sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==} @@ -402,12 +394,12 @@ packages: '@babel/helper-validator-option': 7.18.6 browserslist: 4.20.4 semver: 6.3.1 - dev: false + dev: true /@babel/helper-environment-visitor@7.18.9: resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} engines: {node: '>=6.9.0'} - dev: false + dev: true /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} @@ -452,26 +444,26 @@ packages: '@babel/types': 7.18.9 transitivePeerDependencies: - supports-color - dev: false + dev: true /@babel/helper-plugin-utils@7.18.6: resolution: {integrity: sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg==} engines: {node: '>=6.9.0'} - dev: false + dev: true /@babel/helper-simple-access@7.18.6: resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.18.9 - dev: false + dev: true /@babel/helper-split-export-declaration@7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.18.9 - dev: false + dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} @@ -494,7 +486,7 @@ packages: /@babel/helper-validator-option@7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} engines: {node: '>=6.9.0'} - dev: false + dev: true /@babel/helpers@7.18.9: resolution: {integrity: sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==} @@ -505,7 +497,7 @@ packages: '@babel/types': 7.18.9 transitivePeerDependencies: - supports-color - dev: false + dev: true /@babel/highlight@7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} @@ -514,6 +506,7 @@ packages: '@babel/helper-validator-identifier': 7.18.6 chalk: 2.4.2 js-tokens: 4.0.0 + dev: true /@babel/highlight@7.23.4: resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} @@ -529,7 +522,7 @@ packages: hasBin: true dependencies: '@babel/types': 7.18.9 - dev: false + dev: true /@babel/parser@7.23.9: resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} @@ -545,7 +538,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.18.9): resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} @@ -554,7 +547,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.18.9): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} @@ -563,7 +556,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.18.9): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} @@ -572,7 +565,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.18.9): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} @@ -581,7 +574,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.18.9): resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} @@ -591,7 +584,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.18.9): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} @@ -600,7 +593,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.18.9): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} @@ -609,7 +602,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.18.9): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} @@ -618,7 +611,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.18.9): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} @@ -627,7 +620,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.18.9): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} @@ -636,7 +629,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.18.9): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} @@ -645,7 +638,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.18.9): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} @@ -655,7 +648,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/plugin-syntax-typescript@7.17.12(@babel/core@7.18.9): resolution: {integrity: sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==} @@ -665,7 +658,7 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 - dev: false + dev: true /@babel/runtime@7.17.9: resolution: {integrity: sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==} @@ -678,6 +671,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 + dev: true /@babel/template@7.18.6: resolution: {integrity: sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==} @@ -686,7 +680,7 @@ packages: '@babel/code-frame': 7.23.5 '@babel/parser': 7.18.9 '@babel/types': 7.18.9 - dev: false + dev: true /@babel/template@7.23.9: resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==} @@ -730,13 +724,14 @@ packages: /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: false + dev: true /@cspotcode/source-map-support@0.8.1: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} dependencies: '@jridgewell/trace-mapping': 0.3.9 + dev: true /@emotion/is-prop-valid@0.8.8: resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} @@ -758,6 +753,7 @@ packages: cpu: [arm64] os: [android] requiresBuild: true + dev: true optional: true /@esbuild/android-arm@0.18.20: @@ -766,6 +762,7 @@ packages: cpu: [arm] os: [android] requiresBuild: true + dev: true optional: true /@esbuild/android-x64@0.18.20: @@ -774,6 +771,7 @@ packages: cpu: [x64] os: [android] requiresBuild: true + dev: true optional: true /@esbuild/darwin-arm64@0.18.20: @@ -782,6 +780,7 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true + dev: true optional: true /@esbuild/darwin-x64@0.18.20: @@ -790,6 +789,7 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true + dev: true optional: true /@esbuild/freebsd-arm64@0.18.20: @@ -798,6 +798,7 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true + dev: true optional: true /@esbuild/freebsd-x64@0.18.20: @@ -806,6 +807,7 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true + dev: true optional: true /@esbuild/linux-arm64@0.18.20: @@ -814,6 +816,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-arm@0.18.20: @@ -822,6 +825,7 @@ packages: cpu: [arm] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-ia32@0.18.20: @@ -830,6 +834,7 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-loong64@0.18.20: @@ -838,6 +843,7 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-mips64el@0.18.20: @@ -846,6 +852,7 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-ppc64@0.18.20: @@ -854,6 +861,7 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-riscv64@0.18.20: @@ -862,6 +870,7 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-s390x@0.18.20: @@ -870,6 +879,7 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/linux-x64@0.18.20: @@ -878,6 +888,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: true optional: true /@esbuild/netbsd-x64@0.18.20: @@ -886,6 +897,7 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true + dev: true optional: true /@esbuild/openbsd-x64@0.18.20: @@ -894,6 +906,7 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true + dev: true optional: true /@esbuild/sunos-x64@0.18.20: @@ -902,6 +915,7 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true + dev: true optional: true /@esbuild/win32-arm64@0.18.20: @@ -910,6 +924,7 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true + dev: true optional: true /@esbuild/win32-ia32@0.18.20: @@ -918,6 +933,7 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true + dev: true optional: true /@esbuild/win32-x64@0.18.20: @@ -926,6 +942,7 @@ packages: cpu: [x64] os: [win32] requiresBuild: true + dev: true optional: true /@eslint-community/eslint-utils@4.4.0(eslint@8.48.0): @@ -1050,12 +1067,12 @@ packages: get-package-type: 0.1.0 js-yaml: 3.14.1 resolve-from: 5.0.0 - dev: false + dev: true /@istanbuljs/schema@0.1.3: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - dev: false + dev: true /@jest/console@29.6.4: resolution: {integrity: sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==} @@ -1067,7 +1084,7 @@ packages: jest-message-util: 29.6.3 jest-util: 29.6.3 slash: 3.0.0 - dev: false + dev: true /@jest/core@29.6.4(ts-node@10.9.1): resolution: {integrity: sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==} @@ -1110,7 +1127,7 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: false + dev: true /@jest/create-cache-key-function@29.7.0: resolution: {integrity: sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==} @@ -1127,12 +1144,14 @@ packages: '@jest/types': 29.6.3 '@types/node': 16.11.7 jest-mock: 29.6.3 + dev: true /@jest/expect-utils@29.6.4: resolution: {integrity: sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: jest-get-type: 29.6.3 + dev: true /@jest/expect@29.6.4: resolution: {integrity: sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==} @@ -1142,7 +1161,7 @@ packages: jest-snapshot: 29.6.4 transitivePeerDependencies: - supports-color - dev: false + dev: true /@jest/fake-timers@29.6.4: resolution: {integrity: sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==} @@ -1154,6 +1173,7 @@ packages: jest-message-util: 29.6.3 jest-mock: 29.6.3 jest-util: 29.6.3 + dev: true /@jest/globals@29.6.4: resolution: {integrity: sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==} @@ -1165,7 +1185,7 @@ packages: jest-mock: 29.6.3 transitivePeerDependencies: - supports-color - dev: false + dev: true /@jest/reporters@29.6.4: resolution: {integrity: sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==} @@ -1202,13 +1222,14 @@ packages: v8-to-istanbul: 9.0.1 transitivePeerDependencies: - supports-color - dev: false + dev: true /@jest/schemas@29.6.3: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@sinclair/typebox': 0.27.8 + dev: true /@jest/source-map@29.6.3: resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} @@ -1217,7 +1238,7 @@ packages: '@jridgewell/trace-mapping': 0.3.19 callsites: 3.1.0 graceful-fs: 4.2.10 - dev: false + dev: true /@jest/test-result@29.6.4: resolution: {integrity: sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==} @@ -1227,7 +1248,7 @@ packages: '@jest/types': 29.6.3 '@types/istanbul-lib-coverage': 2.0.3 collect-v8-coverage: 1.0.1 - dev: false + dev: true /@jest/test-sequencer@29.6.4: resolution: {integrity: sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==} @@ -1237,7 +1258,7 @@ packages: graceful-fs: 4.2.10 jest-haste-map: 29.6.4 slash: 3.0.0 - dev: false + dev: true /@jest/transform@29.6.4: resolution: {integrity: sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==} @@ -1260,7 +1281,7 @@ packages: write-file-atomic: 4.0.2 transitivePeerDependencies: - supports-color - dev: false + dev: true /@jest/types@29.6.3: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} @@ -1272,6 +1293,7 @@ packages: '@types/node': 16.11.7 '@types/yargs': 17.0.10 chalk: 4.1.2 + dev: true /@jridgewell/gen-mapping@0.1.1: resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} @@ -1279,7 +1301,7 @@ packages: dependencies: '@jridgewell/set-array': 1.1.1 '@jridgewell/sourcemap-codec': 1.4.15 - dev: false + dev: true /@jridgewell/gen-mapping@0.3.2: resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} @@ -1311,6 +1333,7 @@ packages: dependencies: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + dev: true /@lukeed/csprng@1.1.0: resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} @@ -1459,25 +1482,6 @@ packages: /@popperjs/core@2.9.2: resolution: {integrity: sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==} - /@reduxjs/toolkit@1.8.3(react-redux@8.0.2)(react@18.2.0): - resolution: {integrity: sha512-lU/LDIfORmjBbyDLaqFN2JB9YmAT1BElET9y0ZszwhSBa5Ef3t6o5CrHupw5J1iOXwd+o92QfQZ8OJpwXvsssg==} - peerDependencies: - react: ^16.9.0 || ^17.0.0 || ^18 - react-redux: ^7.2.1 || ^8.0.2 - peerDependenciesMeta: - react: - optional: true - react-redux: - optional: true - dependencies: - immer: 9.0.12 - react: 18.2.0 - react-redux: 8.0.2(@types/react-dom@18.0.5)(@types/react@18.2.21)(react-dom@18.1.0)(react@18.2.0)(redux@4.2.0) - redux: 4.2.0 - redux-thunk: 2.4.1(redux@4.2.0) - reselect: 4.1.5 - dev: false - /@remix-run/router@1.8.0: resolution: {integrity: sha512-mrfKqIHnSZRyIzBcanNJmVQELTnX+qagEDlcKO90RgRBVOZGSGvZKeDihTRfWcqoDn5N/NkUcwWTccnpN18Tfg==} engines: {node: '>=14.0.0'} @@ -1485,16 +1489,19 @@ packages: /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true /@sinonjs/commons@2.0.0: resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} dependencies: type-detect: 4.0.8 + dev: true /@sinonjs/fake-timers@10.0.2: resolution: {integrity: sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==} dependencies: '@sinonjs/commons': 2.0.0 + dev: true /@swc/core-darwin-arm64@1.3.38: resolution: {integrity: sha512-4ZTJJ/cR0EsXW5UxFCifZoGfzQ07a8s4ayt1nLvLQ5QoB1GTAf9zsACpvWG8e7cmCR0L76R5xt8uJuyr+noIXA==} @@ -1502,6 +1509,7 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true + dev: true optional: true /@swc/core-darwin-x64@1.3.38: @@ -1510,6 +1518,7 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true + dev: true optional: true /@swc/core-linux-arm-gnueabihf@1.3.38: @@ -1518,6 +1527,7 @@ packages: cpu: [arm] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-linux-arm64-gnu@1.3.38: @@ -1526,6 +1536,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-linux-arm64-musl@1.3.38: @@ -1534,6 +1545,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-linux-x64-gnu@1.3.38: @@ -1542,6 +1554,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-linux-x64-musl@1.3.38: @@ -1550,6 +1563,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-win32-arm64-msvc@1.3.38: @@ -1558,6 +1572,7 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true + dev: true optional: true /@swc/core-win32-ia32-msvc@1.3.38: @@ -1566,6 +1581,7 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true + dev: true optional: true /@swc/core-win32-x64-msvc@1.3.38: @@ -1574,6 +1590,7 @@ packages: cpu: [x64] os: [win32] requiresBuild: true + dev: true optional: true /@swc/core@1.3.38: @@ -1591,6 +1608,7 @@ packages: '@swc/core-win32-arm64-msvc': 1.3.38 '@swc/core-win32-ia32-msvc': 1.3.38 '@swc/core-win32-x64-msvc': 1.3.38 + dev: true /@swc/counter@0.1.3: resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} @@ -1686,6 +1704,7 @@ packages: dom-accessibility-api: 0.5.10 lz-string: 1.5.0 pretty-format: 27.5.1 + dev: true /@testing-library/jest-dom@5.16.5: resolution: {integrity: sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==} @@ -1714,7 +1733,7 @@ packages: '@types/react-dom': 18.0.5 react: 18.2.0 react-dom: 18.1.0(react@18.2.0) - dev: false + dev: true /@testing-library/user-event@14.4.3(@testing-library/dom@9.3.1): resolution: {integrity: sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==} @@ -1741,15 +1760,19 @@ packages: /@tsconfig/node10@1.0.9: resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true /@tsconfig/node12@1.0.11: resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true /@tsconfig/node14@1.0.3: resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true /@tsconfig/node16@1.0.3: resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} + dev: true /@types/aria-query@4.2.2: resolution: {integrity: sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==} @@ -1757,6 +1780,7 @@ packages: /@types/aria-query@5.0.1: resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} + dev: true /@types/babel__core@7.1.19: resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} @@ -1766,26 +1790,26 @@ packages: '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.17.1 - dev: false + dev: true /@types/babel__generator@7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: '@babel/types': 7.18.9 - dev: false + dev: true /@types/babel__template@7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: '@babel/parser': 7.18.9 '@babel/types': 7.18.9 - dev: false + dev: true /@types/babel__traverse@7.17.1: resolution: {integrity: sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==} dependencies: '@babel/types': 7.18.9 - dev: false + dev: true /@types/eventsource@1.1.11: resolution: {integrity: sha512-L7wLDZlWm5mROzv87W0ofIYeQP5K2UhoFnnUyEWLKM6UBb0ZNRgAqp98qE5DkgfBXdWfc2kYmw9KZm4NLjRbsw==} @@ -1795,7 +1819,7 @@ packages: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: '@types/node': 16.11.7 - dev: false + dev: true /@types/history@4.7.11: resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} @@ -1806,25 +1830,30 @@ packages: dependencies: '@types/react': 18.2.21 hoist-non-react-statics: 3.3.2 + dev: true /@types/istanbul-lib-coverage@2.0.3: resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==} + dev: true /@types/istanbul-lib-report@3.0.0: resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} dependencies: '@types/istanbul-lib-coverage': 2.0.3 + dev: true /@types/istanbul-reports@3.0.1: resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} dependencies: '@types/istanbul-lib-report': 3.0.0 + dev: true /@types/jest@29.0.1: resolution: {integrity: sha512-CAZrjLRZs4xEdIrfrdV74xK1Vo/BKQZwUcjJv3gp6gMeV3BsVxMnXTcgtYOKyphT4DPPo7jxVEVhuwJTQn3oPQ==} dependencies: expect: 29.6.4 pretty-format: 29.6.3 + dev: true /@types/jsdom@20.0.0: resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} @@ -1852,11 +1881,13 @@ packages: /@types/node@16.11.7: resolution: {integrity: sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==} + dev: true /@types/node@20.11.17: resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==} dependencies: undici-types: 5.26.5 + dev: true /@types/parse-json@4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} @@ -1880,6 +1911,7 @@ packages: resolution: {integrity: sha512-OWPWTUrY/NIrjsAPkAk1wW9LZeIjSvkXRhclsFO8CZcZGCOg2G0YZy4ft+rOyYxy8B7ui5iZzi9OkDebZ7/QSA==} dependencies: '@types/react': 18.2.21 + dev: true /@types/react-router-dom@5.3.3: resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} @@ -1908,6 +1940,7 @@ packages: /@types/stack-utils@2.0.1: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + dev: true /@types/styled-components@5.1.18: resolution: {integrity: sha512-xPTYmWP7Mxk5TAD3pYsqjwA9G5fAI8e/S51QUJEl7EQD1siKCdiYXIWiH2lzoHRl+QqbQCJMcGv3YTF3OmyPdQ==} @@ -1921,6 +1954,7 @@ packages: resolution: {integrity: sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==} dependencies: '@types/jest': 29.0.1 + dev: true /@types/tough-cookie@4.0.2: resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} @@ -1932,11 +1966,13 @@ packages: /@types/yargs-parser@20.2.0: resolution: {integrity: sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==} + dev: true /@types/yargs@17.0.10: resolution: {integrity: sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==} dependencies: '@types/yargs-parser': 20.2.0 + dev: true /@typescript-eslint/eslint-plugin@5.29.0(@typescript-eslint/parser@5.62.0)(eslint@8.48.0)(typescript@4.7.4): resolution: {integrity: sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==} @@ -2146,6 +2182,7 @@ packages: /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} + dev: true /acorn@7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} @@ -2163,6 +2200,7 @@ packages: resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} engines: {node: '>=0.4.0'} hasBin: true + dev: true /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -2207,22 +2245,24 @@ packages: engines: {node: '>=8'} dependencies: type-fest: 0.21.3 + dev: true /ansi-escapes@6.0.0: resolution: {integrity: sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw==} engines: {node: '>=14.16'} dependencies: type-fest: 3.6.1 - dev: false + dev: true /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + dev: true /ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} - dev: false + dev: true /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -2235,10 +2275,12 @@ packages: engines: {node: '>=8'} dependencies: color-convert: 2.0.1 + dev: true /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + dev: true /anymatch@3.1.2: resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} @@ -2249,12 +2291,12 @@ packages: /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: sprintf-js: 1.0.3 - dev: false /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -2284,6 +2326,7 @@ packages: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} dependencies: deep-equal: 2.2.2 + dev: true /aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -2296,6 +2339,7 @@ packages: dependencies: call-bind: 1.0.2 is-array-buffer: 3.0.2 + dev: true /array-includes@3.1.5: resolution: {integrity: sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==} @@ -2413,6 +2457,7 @@ packages: /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} + dev: true /axe-core@4.7.2: resolution: {integrity: sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==} @@ -2451,7 +2496,7 @@ packages: slash: 3.0.0 transitivePeerDependencies: - supports-color - dev: false + dev: true /babel-plugin-istanbul@6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} @@ -2464,7 +2509,7 @@ packages: test-exclude: 6.0.0 transitivePeerDependencies: - supports-color - dev: false + dev: true /babel-plugin-jest-hoist@29.6.3: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} @@ -2474,7 +2519,7 @@ packages: '@babel/types': 7.18.9 '@types/babel__core': 7.1.19 '@types/babel__traverse': 7.17.1 - dev: false + dev: true /babel-plugin-styled-components@1.13.2(styled-components@5.3.1): resolution: {integrity: sha512-Vb1R3d4g+MUfPQPVDMCGjm3cDocJEUTR7Xq7QS95JWWeksN1wdFRYpD2kulDgI3Huuaf1CZd+NK4KQmqUFh5dA==} @@ -2508,7 +2553,7 @@ packages: '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.18.9) '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.18.9) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.18.9) - dev: false + dev: true /babel-preset-jest@29.6.3(@babel/core@7.18.9): resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} @@ -2519,10 +2564,11 @@ packages: '@babel/core': 7.18.9 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.0.1(@babel/core@7.18.9) - dev: false + dev: true /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -2545,6 +2591,7 @@ packages: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + dev: true /brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -2572,17 +2619,17 @@ packages: escalade: 3.1.1 node-releases: 2.0.5 picocolors: 1.0.0 - dev: false + dev: true /bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} dependencies: node-int64: 0.4.0 - dev: false + dev: true /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: false + dev: true /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} @@ -2596,6 +2643,7 @@ packages: dependencies: function-bind: 1.1.2 get-intrinsic: 1.2.1 + dev: true /call-me-maybe@1.0.1: resolution: {integrity: sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==} @@ -2604,23 +2652,24 @@ packages: /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + dev: true /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} - dev: false + dev: true /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - dev: false + dev: true /camelize@1.0.0: resolution: {integrity: sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg==} /caniuse-lite@1.0.30001352: resolution: {integrity: sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==} - dev: false + dev: true /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -2644,21 +2693,22 @@ packages: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + dev: true /chalk@5.2.0: resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: false + dev: true /char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} - dev: false + dev: true /char-regex@2.0.1: resolution: {integrity: sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==} engines: {node: '>=12.20'} - dev: false + dev: true /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} @@ -2680,10 +2730,11 @@ packages: /ci-info@3.3.1: resolution: {integrity: sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==} + dev: true /cjs-module-lexer@1.2.2: resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - dev: false + dev: true /classnames@2.3.1: resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} @@ -2712,6 +2763,7 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + dev: true /clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} @@ -2722,7 +2774,7 @@ packages: /co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: false + dev: true /code-block-writer@11.0.1: resolution: {integrity: sha512-0ch9DeCY8v/BWA9n1/Qu1ALG3lpesel4PYL2eNlGLgvGl+J7k74i+dSXSF3wLvF5SYII8/GUT/Ic+fycBR/DUQ==} @@ -2730,7 +2782,7 @@ packages: /collect-v8-coverage@1.0.1: resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - dev: false + dev: true /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -2742,12 +2794,14 @@ packages: engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 + dev: true /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} @@ -2772,6 +2826,7 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true /concurrently@6.5.1: resolution: {integrity: sha512-FlSwNpGjWQfRwPLXvJ/OgysbBxPkWpiVjy1042b0U7on7S7qwwMIILRj7WTN1mTgqa582bG6NFuScOoh6Zgdag==} @@ -2807,17 +2862,17 @@ packages: resolution: {integrity: sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==} dependencies: safe-buffer: 5.1.2 - dev: false + dev: true /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: false + dev: true /core-js@3.14.0: resolution: {integrity: sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA==} deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. requiresBuild: true - dev: false + dev: true /cosmiconfig@7.0.1: resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==} @@ -2832,6 +2887,7 @@ packages: /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} @@ -2840,6 +2896,7 @@ packages: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + dev: true /css-color-keywords@1.0.0: resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} @@ -2929,7 +2986,7 @@ packages: peerDependenciesMeta: babel-plugin-macros: optional: true - dev: false + dev: true /deep-equal@2.2.2: resolution: {integrity: sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==} @@ -2952,6 +3009,7 @@ packages: which-boxed-primitive: 1.0.2 which-collection: 1.0.1 which-typed-array: 1.1.11 + dev: true /deep-is@0.1.3: resolution: {integrity: sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==} @@ -2960,7 +3018,7 @@ packages: /deepmerge@4.2.2: resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} engines: {node: '>=0.10.0'} - dev: false + dev: true /defaults@1.0.3: resolution: {integrity: sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==} @@ -2975,6 +3033,7 @@ packages: dependencies: has-property-descriptors: 1.0.0 object-keys: 1.1.1 + dev: true /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} @@ -2989,7 +3048,7 @@ packages: /detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} - dev: false + dev: true /diff-match-patch@1.0.5: resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} @@ -2998,10 +3057,12 @@ packages: /diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + dev: true /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -3026,6 +3087,7 @@ packages: /dom-accessibility-api@0.5.10: resolution: {integrity: sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==} + dev: true /domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} @@ -3055,20 +3117,21 @@ packages: /electron-to-chromium@1.4.151: resolution: {integrity: sha512-XaG2LpZi9fdiWYOqJh0dJy4SlVywCvpgYXhzOlZTp4JqSKqxn5URqOjbm9OMYB3aInA2GuHQiem1QUOc1yT0Pw==} - dev: false + dev: true /emittery@0.10.2: resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} engines: {node: '>=12'} - dev: false + dev: true /emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} - dev: false + dev: true /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} @@ -3091,6 +3154,7 @@ packages: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 + dev: true /es-abstract@1.22.1: resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} @@ -3149,6 +3213,7 @@ packages: is-string: 1.0.7 isarray: 2.0.5 stop-iteration-iterator: 1.0.0 + dev: true /es-set-tostringtag@2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} @@ -3202,10 +3267,12 @@ packages: '@esbuild/win32-arm64': 0.18.20 '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 + dev: true /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} + dev: true /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} @@ -3214,6 +3281,7 @@ packages: /escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} + dev: true /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} @@ -3614,12 +3682,12 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 strip-final-newline: 2.0.0 - dev: false + dev: true /exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} - dev: false + dev: true /expect@29.6.4: resolution: {integrity: sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==} @@ -3630,6 +3698,7 @@ packages: jest-matcher-utils: 29.6.4 jest-message-util: 29.6.3 jest-util: 29.6.3 + dev: true /external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} @@ -3660,6 +3729,7 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -3679,7 +3749,7 @@ packages: resolution: {integrity: sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==} dependencies: bser: 2.1.1 - dev: false + dev: true /fetch-mock@9.11.0: resolution: {integrity: sha512-PG1XUv+x7iag5p/iNHD4/jdpxL9FtVSqRMUQhPab4hVDt80T1MH5ehzVrL2IdXO9Q2iBggArFvPqjUbHFuI58Q==} @@ -3702,7 +3772,7 @@ packages: whatwg-url: 6.5.0 transitivePeerDependencies: - supports-color - dev: false + dev: true /figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} @@ -3736,7 +3806,7 @@ packages: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - dev: false + dev: true /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} @@ -3772,6 +3842,7 @@ packages: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: is-callable: 1.2.7 + dev: true /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} @@ -3806,6 +3877,7 @@ packages: /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} @@ -3816,6 +3888,7 @@ packages: /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true /function.prototype.name@1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} @@ -3833,15 +3906,17 @@ packages: /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - dev: false + dev: true /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + dev: true /get-intrinsic@1.2.1: resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} @@ -3850,16 +3925,17 @@ packages: has: 1.0.3 has-proto: 1.0.1 has-symbols: 1.0.3 + dev: true /get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} - dev: false + dev: true /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - dev: false + dev: true /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} @@ -3890,7 +3966,7 @@ packages: /glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - dev: false + dev: true /glob@7.1.6: resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} @@ -3912,6 +3988,7 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: true /glob@9.2.1: resolution: {integrity: sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA==} @@ -3955,7 +4032,7 @@ packages: /globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - dev: false + dev: true /goober@2.1.10(csstype@3.1.2): resolution: {integrity: sha512-7PpuQMH10jaTWm33sQgBQvz45pHR8N4l3Cu3WMGEWmHShAcTuuP7I+5/DwKo39fwti5A80WAjvqgz6SSlgWmGA==} @@ -3969,9 +4046,11 @@ packages: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: get-intrinsic: 1.2.1 + dev: true /graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -3988,37 +4067,44 @@ packages: /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + dev: true /has-property-descriptors@1.0.0: resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} dependencies: get-intrinsic: 1.2.1 + dev: true /has-proto@1.0.1: resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} engines: {node: '>= 0.4'} + dev: true /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} + dev: true /has-tostringtag@1.0.0: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 + dev: true /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.2 + dev: true /hasown@2.0.0: resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 + dev: true /hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} @@ -4034,7 +4120,7 @@ packages: /html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: false + dev: true /http-proxy-agent@5.0.0: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} @@ -4060,7 +4146,7 @@ packages: /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - dev: false + dev: true /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} @@ -4085,10 +4171,6 @@ packages: engines: {node: '>= 4'} dev: true - /immer@9.0.12: - resolution: {integrity: sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==} - dev: false - /immutable@4.0.0: resolution: {integrity: sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==} @@ -4107,11 +4189,12 @@ packages: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 - dev: false + dev: true /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + dev: true /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} @@ -4123,9 +4206,11 @@ packages: dependencies: once: 1.4.0 wrappy: 1.0.2 + dev: true /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true /inquirer@8.2.5: resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} @@ -4155,6 +4240,7 @@ packages: get-intrinsic: 1.2.1 has: 1.0.3 side-channel: 1.0.4 + dev: true /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} @@ -4162,6 +4248,7 @@ packages: dependencies: call-bind: 1.0.2 has-tostringtag: 1.0.0 + dev: true /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} @@ -4169,12 +4256,15 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.2.1 is-typed-array: 1.1.12 + dev: true /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true /is-bigint@1.0.2: resolution: {integrity: sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==} + dev: true /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} @@ -4187,10 +4277,12 @@ packages: engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 + dev: true /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} + dev: true /is-core-module@2.13.0: resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} @@ -4202,12 +4294,14 @@ packages: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: hasown: 2.0.0 + dev: true /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 + dev: true /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} @@ -4216,11 +4310,12 @@ packages: /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + dev: true /is-generator-fn@2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} - dev: false + dev: true /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -4235,6 +4330,7 @@ packages: /is-map@2.0.2: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} @@ -4244,6 +4340,7 @@ packages: /is-number-object@1.0.5: resolution: {integrity: sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==} engines: {node: '>= 0.4'} + dev: true /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} @@ -4264,41 +4361,47 @@ packages: dependencies: call-bind: 1.0.2 has-tostringtag: 1.0.0 + dev: true /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: call-bind: 1.0.2 + dev: true /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - dev: false + dev: true /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 + dev: true /is-subset@0.1.1: resolution: {integrity: sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==} - dev: false + dev: true /is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 + dev: true /is-typed-array@1.1.12: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} dependencies: which-typed-array: 1.1.11 + dev: true /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} @@ -4307,6 +4410,7 @@ packages: /is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} @@ -4319,17 +4423,20 @@ packages: dependencies: call-bind: 1.0.2 get-intrinsic: 1.2.1 + dev: true /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true /istanbul-lib-coverage@3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} - dev: false + dev: true /istanbul-lib-instrument@5.2.0: resolution: {integrity: sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==} @@ -4342,7 +4449,7 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: false + dev: true /istanbul-lib-instrument@6.0.0: resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==} @@ -4355,7 +4462,7 @@ packages: semver: 7.5.4 transitivePeerDependencies: - supports-color - dev: false + dev: true /istanbul-lib-report@3.0.0: resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} @@ -4364,7 +4471,7 @@ packages: istanbul-lib-coverage: 3.2.0 make-dir: 3.1.0 supports-color: 7.2.0 - dev: false + dev: true /istanbul-lib-source-maps@4.0.1: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} @@ -4375,7 +4482,7 @@ packages: source-map: 0.6.1 transitivePeerDependencies: - supports-color - dev: false + dev: true /istanbul-reports@3.1.4: resolution: {integrity: sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==} @@ -4383,7 +4490,7 @@ packages: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.0 - dev: false + dev: true /iterare@1.2.1: resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} @@ -4408,7 +4515,7 @@ packages: execa: 5.1.1 jest-util: 29.6.3 p-limit: 3.1.0 - dev: false + dev: true /jest-circus@29.6.4: resolution: {integrity: sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==} @@ -4437,7 +4544,7 @@ packages: transitivePeerDependencies: - babel-plugin-macros - supports-color - dev: false + dev: true /jest-cli@29.6.4(@types/node@20.11.17)(ts-node@10.9.1): resolution: {integrity: sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==} @@ -4466,7 +4573,7 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: false + dev: true /jest-config@29.6.4(@types/node@16.11.7)(ts-node@10.9.1): resolution: {integrity: sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==} @@ -4507,7 +4614,7 @@ packages: transitivePeerDependencies: - babel-plugin-macros - supports-color - dev: false + dev: true /jest-config@29.6.4(@types/node@20.11.17)(ts-node@10.9.1): resolution: {integrity: sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==} @@ -4548,7 +4655,7 @@ packages: transitivePeerDependencies: - babel-plugin-macros - supports-color - dev: false + dev: true /jest-diff@29.6.4: resolution: {integrity: sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==} @@ -4558,13 +4665,14 @@ packages: diff-sequences: 29.6.3 jest-get-type: 29.6.3 pretty-format: 29.6.3 + dev: true /jest-docblock@29.6.3: resolution: {integrity: sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: detect-newline: 3.1.0 - dev: false + dev: true /jest-each@29.6.3: resolution: {integrity: sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==} @@ -4575,7 +4683,7 @@ packages: jest-get-type: 29.6.3 jest-util: 29.6.3 pretty-format: 29.6.3 - dev: false + dev: true /jest-environment-jsdom@29.6.4: resolution: {integrity: sha512-K6wfgUJ16DoMs02JYFid9lOsqfpoVtyJxpRlnTxUHzvZWBnnh2VNGRB9EC1Cro96TQdq5TtSjb3qUjNaJP9IyA==} @@ -4610,11 +4718,12 @@ packages: '@types/node': 16.11.7 jest-mock: 29.6.3 jest-util: 29.6.3 - dev: false + dev: true /jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true /jest-haste-map@29.6.4: resolution: {integrity: sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==} @@ -4633,7 +4742,7 @@ packages: walker: 1.0.8 optionalDependencies: fsevents: 2.3.2 - dev: false + dev: true /jest-leak-detector@29.6.3: resolution: {integrity: sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==} @@ -4641,7 +4750,7 @@ packages: dependencies: jest-get-type: 29.6.3 pretty-format: 29.6.3 - dev: false + dev: true /jest-matcher-utils@29.6.4: resolution: {integrity: sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==} @@ -4651,6 +4760,7 @@ packages: jest-diff: 29.6.4 jest-get-type: 29.6.3 pretty-format: 29.6.3 + dev: true /jest-message-util@29.6.3: resolution: {integrity: sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==} @@ -4665,6 +4775,7 @@ packages: pretty-format: 29.6.3 slash: 3.0.0 stack-utils: 2.0.5 + dev: true /jest-mock@29.6.3: resolution: {integrity: sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==} @@ -4673,6 +4784,7 @@ packages: '@jest/types': 29.6.3 '@types/node': 16.11.7 jest-util: 29.6.3 + dev: true /jest-pnp-resolver@1.2.2(jest-resolve@29.6.4): resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} @@ -4684,17 +4796,17 @@ packages: optional: true dependencies: jest-resolve: 29.6.4 - dev: false + dev: true /jest-regex-util@29.0.0: resolution: {integrity: sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: false + dev: true /jest-regex-util@29.6.3: resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: false + dev: true /jest-resolve-dependencies@29.6.4: resolution: {integrity: sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==} @@ -4704,7 +4816,7 @@ packages: jest-snapshot: 29.6.4 transitivePeerDependencies: - supports-color - dev: false + dev: true /jest-resolve@29.6.4: resolution: {integrity: sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==} @@ -4719,7 +4831,7 @@ packages: resolve: 1.22.4 resolve.exports: 2.0.1 slash: 3.0.0 - dev: false + dev: true /jest-runner@29.6.4: resolution: {integrity: sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==} @@ -4748,7 +4860,7 @@ packages: source-map-support: 0.5.13 transitivePeerDependencies: - supports-color - dev: false + dev: true /jest-runtime@29.6.4: resolution: {integrity: sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==} @@ -4778,7 +4890,7 @@ packages: strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - dev: false + dev: true /jest-snapshot@29.6.4: resolution: {integrity: sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==} @@ -4806,7 +4918,7 @@ packages: semver: 7.5.4 transitivePeerDependencies: - supports-color - dev: false + dev: true /jest-sonar-reporter@2.0.0: resolution: {integrity: sha512-ZervDCgEX5gdUbdtWsjdipLN3bKJwpxbvhkYNXTAYvAckCihobSLr9OT/IuyNIRT1EZMDDwR6DroWtrq+IL64w==} @@ -4835,6 +4947,7 @@ packages: ci-info: 3.3.1 graceful-fs: 4.2.10 picomatch: 2.3.1 + dev: true /jest-validate@29.6.3: resolution: {integrity: sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==} @@ -4846,7 +4959,7 @@ packages: jest-get-type: 29.6.3 leven: 3.1.0 pretty-format: 29.6.3 - dev: false + dev: true /jest-watch-typeahead@2.2.2(jest@29.6.4): resolution: {integrity: sha512-+QgOFW4o5Xlgd6jGS5X37i08tuuXNW8X0CV9WNFi+3n8ExCIP+E1melYhvYLjv5fE6D0yyzk74vsSO8I6GqtvQ==} @@ -4862,7 +4975,7 @@ packages: slash: 5.0.0 string-length: 5.0.1 strip-ansi: 7.0.1 - dev: false + dev: true /jest-watcher@29.0.3: resolution: {integrity: sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw==} @@ -4876,7 +4989,7 @@ packages: emittery: 0.10.2 jest-util: 29.6.3 string-length: 4.0.2 - dev: false + dev: true /jest-watcher@29.6.4: resolution: {integrity: sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==} @@ -4890,7 +5003,7 @@ packages: emittery: 0.13.1 jest-util: 29.6.3 string-length: 4.0.2 - dev: false + dev: true /jest-worker@29.6.4: resolution: {integrity: sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==} @@ -4900,7 +5013,7 @@ packages: jest-util: 29.6.3 merge-stream: 2.0.0 supports-color: 8.1.1 - dev: false + dev: true /jest@29.6.4(@types/node@20.11.17)(ts-node@10.9.1): resolution: {integrity: sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==} @@ -4921,7 +5034,7 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: false + dev: true /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -4932,7 +5045,6 @@ packages: dependencies: argparse: 1.0.10 esprima: 4.0.1 - dev: false /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} @@ -4990,6 +5102,7 @@ packages: /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true /json-schema-faker@0.5.6: resolution: {integrity: sha512-u/cFC26/GDxh2vPiAC8B8xVvpXAW+QYtG2mijEbKrimCk8IHtiwQBjCE8TwvowdhALWq9IcdIWZ+/8ocXvdL3Q==} @@ -5031,6 +5144,7 @@ packages: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true + dev: true /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} @@ -5070,7 +5184,7 @@ packages: /kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} - dev: false + dev: true /language-subtag-registry@0.3.21: resolution: {integrity: sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==} @@ -5085,7 +5199,7 @@ packages: /leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} - dev: false + dev: true /levn@0.3.0: resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} @@ -5105,13 +5219,14 @@ packages: /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} dependencies: p-locate: 4.1.0 - dev: false + dev: true /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} @@ -5126,7 +5241,6 @@ packages: /lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - dev: false /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -5134,7 +5248,7 @@ packages: /lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - dev: false + dev: true /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -5162,6 +5276,7 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 + dev: true /lru-cache@7.18.3: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} @@ -5171,26 +5286,28 @@ packages: /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + dev: true /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} dependencies: semver: 6.3.1 - dev: false + dev: true /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true /makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} dependencies: tmpl: 1.0.5 - dev: false + dev: true /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: false + dev: true /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} @@ -5203,6 +5320,7 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 + dev: true /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} @@ -5219,6 +5337,7 @@ packages: /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + dev: true /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} @@ -5229,6 +5348,7 @@ packages: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 + dev: true /minimatch@5.1.2: resolution: {integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==} @@ -5274,9 +5394,11 @@ packages: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + dev: true /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} @@ -5292,11 +5414,11 @@ packages: /node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: false + dev: true /node-releases@2.0.5: resolution: {integrity: sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==} - dev: false + dev: true /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -5307,6 +5429,7 @@ packages: engines: {node: '>=8'} dependencies: path-key: 3.1.1 + dev: true /nwsapi@2.2.0: resolution: {integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==} @@ -5318,6 +5441,7 @@ packages: /object-inspect@1.12.3: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true /object-is@1.1.5: resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} @@ -5325,10 +5449,12 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.2.0 + dev: true /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} + dev: true /object.assign@4.1.2: resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==} @@ -5348,6 +5474,7 @@ packages: define-properties: 1.2.0 has-symbols: 1.0.3 object-keys: 1.1.1 + dev: true /object.entries@1.1.5: resolution: {integrity: sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==} @@ -5423,12 +5550,14 @@ packages: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 + dev: true /onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 + dev: true /ono@4.0.11: resolution: {integrity: sha512-jQ31cORBFE6td25deYeD80wxKBMj+zBmHTrVxnc6CKhx8gho6ipmWM5zj/oeoqioZ99yqBls9Z/9Nss7J26G2g==} @@ -5485,20 +5614,21 @@ packages: engines: {node: '>=6'} dependencies: p-try: 2.2.0 - dev: false + dev: true /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} dependencies: yocto-queue: 0.1.0 + dev: true /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} dependencies: p-limit: 2.3.0 - dev: false + dev: true /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} @@ -5510,7 +5640,7 @@ packages: /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - dev: false + dev: true /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -5527,6 +5657,7 @@ packages: error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + dev: true /parse-ms@2.1.0: resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} @@ -5546,17 +5677,21 @@ packages: /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + dev: true /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + dev: true /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + dev: true /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true /path-scurry@1.6.1: resolution: {integrity: sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==} @@ -5568,7 +5703,7 @@ packages: /path-to-regexp@2.4.0: resolution: {integrity: sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==} - dev: false + dev: true /path-to-regexp@3.2.0: resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} @@ -5581,6 +5716,7 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -5589,14 +5725,14 @@ packages: /pirates@4.0.5: resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} engines: {node: '>= 6'} - dev: false + dev: true /pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} dependencies: find-up: 4.1.0 - dev: false + dev: true /postcss-value-parser@4.1.0: resolution: {integrity: sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==} @@ -5608,6 +5744,7 @@ packages: nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 + dev: true /prelude-ls@1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} @@ -5639,6 +5776,7 @@ packages: ansi-regex: 5.0.1 ansi-styles: 5.2.0 react-is: 17.0.2 + dev: true /pretty-format@29.6.3: resolution: {integrity: sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==} @@ -5647,6 +5785,7 @@ packages: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.2.0 + dev: true /pretty-ms@7.0.1: resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} @@ -5661,7 +5800,7 @@ packages: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 - dev: false + dev: true /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -5688,13 +5827,13 @@ packages: /pure-rand@6.0.0: resolution: {integrity: sha512-rLSBxJjP+4DQOgcJAx6RZHT2he2pkhQdSnofG5VWyVl6GRq/K02ISOuOLcsMOrtKDIJb8JN2zm3FFzWNbezdPw==} - dev: false + dev: true /querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} engines: {node: '>=0.4.x'} deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. - dev: false + dev: true /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -5785,6 +5924,7 @@ packages: /react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} @@ -5835,40 +5975,6 @@ packages: warning: 4.0.3 dev: false - /react-redux@8.0.2(@types/react-dom@18.0.5)(@types/react@18.2.21)(react-dom@18.1.0)(react@18.2.0)(redux@4.2.0): - resolution: {integrity: sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==} - peerDependencies: - '@types/react': ^16.8 || ^17.0 || ^18.0 - '@types/react-dom': ^16.8 || ^17.0 || ^18.0 - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - react-native: '>=0.59' - redux: ^4 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - react-dom: - optional: true - react-native: - optional: true - redux: - optional: true - dependencies: - '@babel/runtime': 7.17.9 - '@types/hoist-non-react-statics': 3.3.1 - '@types/react': 18.2.21 - '@types/react-dom': 18.0.5 - '@types/use-sync-external-store': 0.0.3 - hoist-non-react-statics: 3.3.2 - react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) - react-is: 18.2.0 - redux: 4.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) - dev: false - /react-router-dom@6.15.0(react-dom@18.1.0)(react@18.2.0): resolution: {integrity: sha512-aR42t0fs7brintwBGAv2+mGlCtgtFQeOzK0BM1/OiqEzRejOZtpMZepvgkscpMUnKb8YO84G7s3LsHnnDNonbQ==} engines: {node: '>=14.0.0'} @@ -5931,20 +6037,6 @@ packages: strip-indent: 3.0.0 dev: true - /redux-thunk@2.4.1(redux@4.2.0): - resolution: {integrity: sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==} - peerDependencies: - redux: ^4 - dependencies: - redux: 4.2.0 - dev: false - - /redux@4.2.0: - resolution: {integrity: sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==} - dependencies: - '@babel/runtime': 7.17.9 - dev: false - /reflect-metadata@0.1.13: resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} dev: true @@ -5954,6 +6046,7 @@ packages: /regenerator-runtime@0.14.0: resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + dev: true /regexp.prototype.flags@1.5.0: resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} @@ -5962,6 +6055,7 @@ packages: call-bind: 1.0.2 define-properties: 1.2.0 functions-have-names: 1.2.3 + dev: true /regexpp@3.2.0: resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} @@ -5971,6 +6065,7 @@ packages: /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + dev: true /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} @@ -5986,16 +6081,12 @@ packages: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: true - /reselect@4.1.5: - resolution: {integrity: sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==} - dev: false - /resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} dependencies: resolve-from: 5.0.0 - dev: false + dev: true /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} @@ -6005,7 +6096,7 @@ packages: /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - dev: false + dev: true /resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -6014,7 +6105,7 @@ packages: /resolve.exports@2.0.1: resolution: {integrity: sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==} engines: {node: '>=10'} - dev: false + dev: true /resolve@1.22.4: resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} @@ -6023,6 +6114,7 @@ packages: is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + dev: true /resolve@2.0.0-next.3: resolution: {integrity: sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==} @@ -6065,6 +6157,7 @@ packages: hasBin: true optionalDependencies: fsevents: 2.3.2 + dev: true /run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} @@ -6102,7 +6195,7 @@ packages: /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: false + dev: true /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -6144,6 +6237,7 @@ packages: /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + dev: true /semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} @@ -6151,6 +6245,7 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 + dev: true /shallowequal@1.1.0: resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} @@ -6160,10 +6255,12 @@ packages: engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 + dev: true /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + dev: true /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} @@ -6171,22 +6268,25 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.2.1 object-inspect: 1.12.3 + dev: true /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: false + dev: true /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + dev: true /slash@5.0.0: resolution: {integrity: sha512-n6KkmvKS0623igEVj3FF0OZs1gYYJ0o0Hj939yc1fyxl2xt+xYpLnzJB6xBSqOfV9ZFLEWodBBN/heZJahuIJQ==} engines: {node: '>=14.16'} - dev: false + dev: true /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} @@ -6197,11 +6297,12 @@ packages: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: false + dev: true /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + dev: true /spawn-command@0.0.2-1: resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} @@ -6209,19 +6310,20 @@ packages: /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: false /stack-utils@2.0.5: resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} engines: {node: '>=10'} dependencies: escape-string-regexp: 2.0.0 + dev: true /stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} dependencies: internal-slot: 1.0.5 + dev: true /string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} @@ -6229,7 +6331,7 @@ packages: dependencies: char-regex: 1.0.2 strip-ansi: 6.0.1 - dev: false + dev: true /string-length@5.0.1: resolution: {integrity: sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==} @@ -6237,7 +6339,7 @@ packages: dependencies: char-regex: 2.0.1 strip-ansi: 7.0.1 - dev: false + dev: true /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -6246,6 +6348,7 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + dev: true /string.prototype.matchall@4.0.7: resolution: {integrity: sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==} @@ -6296,13 +6399,14 @@ packages: engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 + dev: true /strip-ansi@7.0.1: resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} engines: {node: '>=12'} dependencies: ansi-regex: 6.0.1 - dev: false + dev: true /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} @@ -6312,12 +6416,12 @@ packages: /strip-bom@4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} - dev: false + dev: true /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} - dev: false + dev: true /strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} @@ -6329,6 +6433,7 @@ packages: /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + dev: true /styled-components@5.3.1(react-dom@18.1.0)(react-is@18.2.0)(react@18.2.0): resolution: {integrity: sha512-JThv2JRzyH0NOIURrk9iskdxMSAAtCfj/b2Sf1WJaCUsloQkblepy1jaCLX/bYE+mhYo3unmwVSI9I5d9ncSiQ==} @@ -6363,16 +6468,19 @@ packages: engines: {node: '>=8'} dependencies: has-flag: 4.0.0 + dev: true /supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} dependencies: has-flag: 4.0.0 + dev: true /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + dev: true /symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -6394,7 +6502,7 @@ packages: '@istanbuljs/schema': 0.1.3 glob: 7.2.0 minimatch: 3.1.2 - dev: false + dev: true /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -6421,7 +6529,7 @@ packages: /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: false + dev: true /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} @@ -6455,7 +6563,7 @@ packages: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} dependencies: punycode: 2.1.1 - dev: false + dev: true /tr46@3.0.0: resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} @@ -6511,6 +6619,7 @@ packages: typescript: 4.7.4 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + dev: true /ts-prune@0.10.3: resolution: {integrity: sha512-iS47YTbdIcvN8Nh/1BFyziyUqmjXz7GVzWu02RaZXqb+e/3Qe1B7IQ4860krOeCGUeJmterAlaM2FRH0Ue0hjw==} @@ -6535,7 +6644,7 @@ packages: optional: true dependencies: typescript: 4.7.4 - dev: false + dev: true /tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -6584,6 +6693,7 @@ packages: /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + dev: true /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} @@ -6593,6 +6703,7 @@ packages: /type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + dev: true /type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} @@ -6602,7 +6713,7 @@ packages: /type-fest@3.6.1: resolution: {integrity: sha512-htXWckxlT6U4+ilVgweNliPqlsVSSucbxVexRYllyMVJDtf5rTjv6kF/s+qAd4QSL1BZcnJPEJavYBPQiWuZDA==} engines: {node: '>=14.16'} - dev: false + dev: true /typed-array-buffer@1.0.0: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} @@ -6646,6 +6757,7 @@ packages: resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} engines: {node: '>=4.2.0'} hasBin: true + dev: true /uid@2.0.1: resolution: {integrity: sha512-PF+1AnZgycpAIEmNtjxGBVmKbZAQguaa4pBUq6KNaGEcpzZ2klCNZLM34tsjp76maN00TttiiUf6zkIBpJQm2A==} @@ -6665,6 +6777,7 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true /universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} @@ -6711,6 +6824,7 @@ packages: /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true /v8-to-istanbul@9.0.1: resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==} @@ -6719,7 +6833,7 @@ packages: '@jridgewell/trace-mapping': 0.3.19 '@types/istanbul-lib-coverage': 2.0.3 convert-source-map: 1.7.0 - dev: false + dev: true /vite-plugin-checker@0.6.4(eslint@8.48.0)(typescript@4.7.4)(vite@4.5.3): resolution: {integrity: sha512-2zKHH5oxr+ye43nReRbC2fny1nyARwhxdm0uNYp/ERy4YvU9iZpNOsueoi/luXw5gnpqRSvjcEPxXbS153O2wA==} @@ -6793,7 +6907,7 @@ packages: transitivePeerDependencies: - supports-color - typescript - dev: false + dev: true /vite@4.5.3(@types/node@20.11.17)(sass@1.66.1): resolution: {integrity: sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==} @@ -6830,6 +6944,7 @@ packages: sass: 1.66.1 optionalDependencies: fsevents: 2.3.2 + dev: true /vscode-jsonrpc@6.0.0: resolution: {integrity: sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==} @@ -6889,7 +7004,7 @@ packages: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} dependencies: makeerror: 1.0.12 - dev: false + dev: true /warning@4.0.3: resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} @@ -6908,7 +7023,7 @@ packages: /webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - dev: false + dev: true /webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} @@ -6924,7 +7039,7 @@ packages: /whatwg-fetch@3.6.2: resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==} - dev: false + dev: true /whatwg-mimetype@3.0.0: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} @@ -6952,7 +7067,7 @@ packages: lodash.sortby: 4.7.0 tr46: 1.0.1 webidl-conversions: 4.0.2 - dev: false + dev: true /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -6962,6 +7077,7 @@ packages: is-number-object: 1.0.5 is-string: 1.0.7 is-symbol: 1.0.4 + dev: true /which-collection@1.0.1: resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} @@ -6970,6 +7086,7 @@ packages: is-set: 2.0.2 is-weakmap: 2.0.1 is-weakset: 2.0.2 + dev: true /which-typed-array@1.1.11: resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} @@ -6980,6 +7097,7 @@ packages: for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 + dev: true /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} @@ -6987,6 +7105,7 @@ packages: hasBin: true dependencies: isexe: 2.0.0 + dev: true /word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} @@ -7000,9 +7119,11 @@ packages: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 + dev: true /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true /write-file-atomic@4.0.2: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} @@ -7010,7 +7131,7 @@ packages: dependencies: imurmurhash: 0.1.4 signal-exit: 3.0.7 - dev: false + dev: true /ws@8.8.0: resolution: {integrity: sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==} @@ -7041,9 +7162,11 @@ packages: /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + dev: true /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true /yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} @@ -7058,7 +7181,7 @@ packages: /yargs-parser@21.0.1: resolution: {integrity: sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==} engines: {node: '>=12'} - dev: false + dev: true /yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} @@ -7084,15 +7207,17 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.0.1 - dev: false + dev: true /yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} + dev: true /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + dev: true /yup@1.3.3: resolution: {integrity: sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw==} diff --git a/frontend/src/components/ACLPage/Form/CustomACL/Form.tsx b/frontend/src/components/ACLPage/Form/CustomACL/Form.tsx index a0cf8d0ba..720666972 100644 --- a/frontend/src/components/ACLPage/Form/CustomACL/Form.tsx +++ b/frontend/src/components/ACLPage/Form/CustomACL/Form.tsx @@ -7,10 +7,10 @@ import Input from 'components/common/Input/Input'; import ControlledSelect from 'components/common/Select/ControlledSelect'; import { matchTypeOptions } from 'components/ACLPage/Form/constants'; import useAppParams from 'lib/hooks/useAppParams'; -import { ClusterName } from 'redux/interfaces'; import * as S from 'components/ACLPage/Form/Form.styled'; import ACLFormContext from 'components/ACLPage/Form/AclFormContext'; import { AclDetailedFormProps } from 'components/ACLPage/Form/types'; +import { ClusterName } from 'lib/interfaces/cluster'; import formSchema from './schema'; import { FormValues } from './types'; diff --git a/frontend/src/components/ACLPage/Form/ForConsumers/Form.tsx b/frontend/src/components/ACLPage/Form/ForConsumers/Form.tsx index febd75e08..9db8f7498 100644 --- a/frontend/src/components/ACLPage/Form/ForConsumers/Form.tsx +++ b/frontend/src/components/ACLPage/Form/ForConsumers/Form.tsx @@ -1,7 +1,7 @@ import React, { FC, useContext } from 'react'; import { yupResolver } from '@hookform/resolvers/yup'; import { FormProvider, useForm } from 'react-hook-form'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { useCreateConsumersAcl } from 'lib/hooks/api/acl'; import useAppParams from 'lib/hooks/useAppParams'; import ControlledMultiSelect from 'components/common/MultiSelect/ControlledMultiSelect'; diff --git a/frontend/src/components/ACLPage/Form/ForKafkaStreamApps/Form.tsx b/frontend/src/components/ACLPage/Form/ForKafkaStreamApps/Form.tsx index 7a747de4e..c03e41c89 100644 --- a/frontend/src/components/ACLPage/Form/ForKafkaStreamApps/Form.tsx +++ b/frontend/src/components/ACLPage/Form/ForKafkaStreamApps/Form.tsx @@ -1,7 +1,7 @@ import React, { FC, useContext } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { useCreateStreamAppAcl } from 'lib/hooks/api/acl'; import useAppParams from 'lib/hooks/useAppParams'; import Input from 'components/common/Input/Input'; diff --git a/frontend/src/components/ACLPage/Form/ForProducers/Form.tsx b/frontend/src/components/ACLPage/Form/ForProducers/Form.tsx index cd84aa674..c23816de8 100644 --- a/frontend/src/components/ACLPage/Form/ForProducers/Form.tsx +++ b/frontend/src/components/ACLPage/Form/ForProducers/Form.tsx @@ -3,7 +3,7 @@ import { yupResolver } from '@hookform/resolvers/yup'; import { useCreateProducerAcl } from 'lib/hooks/api/acl'; import { FormProvider, useForm } from 'react-hook-form'; import useAppParams from 'lib/hooks/useAppParams'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import Input from 'components/common/Input/Input'; import ControlledMultiSelect from 'components/common/MultiSelect/ControlledMultiSelect'; import Checkbox from 'components/common/Checkbox/Checkbox'; diff --git a/frontend/src/components/ACLPage/List/List.tsx b/frontend/src/components/ACLPage/List/List.tsx index ddf60d419..c2befd89c 100644 --- a/frontend/src/components/ACLPage/List/List.tsx +++ b/frontend/src/components/ACLPage/List/List.tsx @@ -5,7 +5,7 @@ import Table from 'components/common/NewTable'; import { useConfirm } from 'lib/hooks/useConfirm'; import useAppParams from 'lib/hooks/useAppParams'; import { useAcls, useDeleteAcl } from 'lib/hooks/api/acl'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { KafkaAcl, KafkaAclNamePatternType, diff --git a/frontend/src/components/Brokers/BrokersList/BrokersList.tsx b/frontend/src/components/Brokers/BrokersList/BrokersList.tsx index bdc1f9c00..3ef59d0b5 100644 --- a/frontend/src/components/Brokers/BrokersList/BrokersList.tsx +++ b/frontend/src/components/Brokers/BrokersList/BrokersList.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { useNavigate } from 'react-router-dom'; import PageHeading from 'components/common/PageHeading/PageHeading'; import useAppParams from 'lib/hooks/useAppParams'; diff --git a/frontend/src/components/ConsumerGroups/Details/ListItem.tsx b/frontend/src/components/ConsumerGroups/Details/ListItem.tsx index 99a3c0bd8..57b7cb133 100644 --- a/frontend/src/components/ConsumerGroups/Details/ListItem.tsx +++ b/frontend/src/components/ConsumerGroups/Details/ListItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ConsumerGroupTopicPartition } from 'generated-sources'; import { Link } from 'react-router-dom'; -import { ClusterName } from 'redux/interfaces/cluster'; +import { ClusterName } from 'lib/interfaces/cluster'; import { clusterTopicPath } from 'lib/paths'; import MessageToggleIcon from 'components/common/Icons/MessageToggleIcon'; import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper'; diff --git a/frontend/src/components/KsqlDb/Query/renderer/TableRenderer/TableRenderer.tsx b/frontend/src/components/KsqlDb/Query/renderer/TableRenderer/TableRenderer.tsx index 4e1acb38d..c6ae3efd1 100644 --- a/frontend/src/components/KsqlDb/Query/renderer/TableRenderer/TableRenderer.tsx +++ b/frontend/src/components/KsqlDb/Query/renderer/TableRenderer/TableRenderer.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { KsqlTableResponse } from 'generated-sources'; import TableHeaderCell from 'components/common/table/TableHeaderCell/TableHeaderCell'; -import { nanoid } from '@reduxjs/toolkit'; import { TableTitle } from 'components/common/table/TableTitle/TableTitle.styled'; +import { nanoid } from 'lib/functions/nanoid'; import * as S from './TableRenderer.styled'; @@ -15,17 +15,13 @@ function hasJsonStructure(str: string | Record): boolean { return true; } - if (typeof str === 'string') { - try { - const result = JSON.parse(str); - const type = Object.prototype.toString.call(result); - return type === '[object Object]' || type === '[object Array]'; - } catch (err) { - return false; - } + try { + const result = JSON.parse(str); + const type = Object.prototype.toString.call(result); + return type === '[object Object]' || type === '[object Array]'; + } catch (err) { + return false; } - - return false; } const TableRenderer: React.FC = ({ table }) => { diff --git a/frontend/src/components/Schemas/Details/Details.tsx b/frontend/src/components/Schemas/Details/Details.tsx index 4204e647b..2d0c345d7 100644 --- a/frontend/src/components/Schemas/Details/Details.tsx +++ b/frontend/src/components/Schemas/Details/Details.tsx @@ -10,23 +10,8 @@ import ClusterContext from 'components/contexts/ClusterContext'; import PageLoader from 'components/common/PageLoader/PageLoader'; import PageHeading from 'components/common/PageHeading/PageHeading'; import { Button } from 'components/common/Button/Button'; -import { useAppDispatch, useAppSelector } from 'lib/hooks/redux'; -import { - fetchLatestSchema, - fetchSchemaVersions, - getAreSchemaLatestFulfilled, - getAreSchemaVersionsFulfilled, - SCHEMAS_VERSIONS_FETCH_ACTION, - SCHEMA_LATEST_FETCH_ACTION, - selectAllSchemaVersions, - getSchemaLatest, - getAreSchemaLatestRejected, -} from 'redux/reducers/schemas/schemasSlice'; -import { showServerError } from 'lib/errorHandling'; -import { resetLoaderById } from 'redux/reducers/loader/loaderSlice'; import { TableTitle } from 'components/common/table/TableTitle/TableTitle.styled'; import useAppParams from 'lib/hooks/useAppParams'; -import { schemasApiClient } from 'lib/api'; import { Dropdown } from 'components/common/Dropdown'; import Table from 'components/common/NewTable'; import { Action, ResourceType } from 'generated-sources'; @@ -34,35 +19,37 @@ import { ActionButton, ActionDropdownItem, } from 'components/common/ActionComponent'; +import { + useDeleteSchema, + useGetLatestSchema, + useGetSchemasVersions, +} from 'lib/hooks/api/schemas'; import LatestVersionItem from './LatestVersion/LatestVersionItem'; import SchemaVersion from './SchemaVersion/SchemaVersion'; const Details: React.FC = () => { const navigate = useNavigate(); - const dispatch = useAppDispatch(); const { isReadOnly } = React.useContext(ClusterContext); const { clusterName, subject } = useAppParams(); + const { data: versions = [], isFetching: areVersionsFetching } = + useGetSchemasVersions({ + clusterName, + subject, + }); + const { + data: schema, + isFetching: isSchemaFetching, + isError: isErrorLatestSchema, + } = useGetLatestSchema({ + clusterName, + subject, + }); - React.useEffect(() => { - dispatch(fetchLatestSchema({ clusterName, subject })); - return () => { - dispatch(resetLoaderById(SCHEMA_LATEST_FETCH_ACTION)); - }; - }, [clusterName, dispatch, subject]); - - React.useEffect(() => { - dispatch(fetchSchemaVersions({ clusterName, subject })); - return () => { - dispatch(resetLoaderById(SCHEMAS_VERSIONS_FETCH_ACTION)); - }; - }, [clusterName, dispatch, subject]); - - const versions = useAppSelector((state) => selectAllSchemaVersions(state)); - const schema = useAppSelector(getSchemaLatest); - const isFetched = useAppSelector(getAreSchemaLatestFulfilled); - const isRejected = useAppSelector(getAreSchemaLatestRejected); - const areVersionsFetched = useAppSelector(getAreSchemaVersionsFulfilled); + const { mutateAsync: deleteSchema } = useDeleteSchema({ + clusterName, + subject, + }); const columns = React.useMemo( () => [ @@ -74,28 +61,18 @@ const Details: React.FC = () => { ); const deleteHandler = async () => { - try { - await schemasApiClient.deleteSchema({ - clusterName, - subject, - }); - navigate('../'); - } catch (e) { - showServerError(e as Response); - } + await deleteSchema(); + navigate('../'); }; - if (isRejected) { - navigate('/404'); - } - - if (!isFetched || !schema) { + if (isSchemaFetching || areVersionsFetching || isErrorLatestSchema) { return ; } + return ( <> @@ -144,9 +121,11 @@ const Details: React.FC = () => { )} - + {schema && } Old versions - {areVersionsFetched ? ( + {areVersionsFetching ? ( + + ) : ( { renderSubComponent={SchemaVersion} enableSorting /> - ) : ( - )} ); diff --git a/frontend/src/components/Schemas/Details/__test__/Details.spec.tsx b/frontend/src/components/Schemas/Details/__test__/Details.spec.tsx index 3b58c376e..ef40efa2d 100644 --- a/frontend/src/components/Schemas/Details/__test__/Details.spec.tsx +++ b/frontend/src/components/Schemas/Details/__test__/Details.spec.tsx @@ -4,23 +4,22 @@ import { render, WithRoute } from 'lib/testHelpers'; import { clusterSchemaPath } from 'lib/paths'; import { screen } from '@testing-library/dom'; import { - schemasInitialState, schemaVersion, schemaVersionWithNonAsciiChars, -} from 'redux/reducers/schemas/__test__/fixtures'; -import fetchMock from 'fetch-mock'; +} from 'components/Schemas/Edit/__tests__/fixtures'; import ClusterContext, { ContextProps, initialValue as contextInitialValue, } from 'components/contexts/ClusterContext'; -import { RootState } from 'redux/interfaces'; -import { act } from '@testing-library/react'; +import { + useDeleteSchema, + useGetLatestSchema, + useGetSchemasVersions, +} from 'lib/hooks/api/schemas'; import { versionPayload, versionEmptyPayload } from './fixtures'; const clusterName = 'testClusterName'; -const schemasAPILatestUrl = `/api/clusters/${clusterName}/schemas/${schemaVersion.subject}/latest`; -const schemasAPIVersionsUrl = `/api/clusters/${clusterName}/schemas/${schemaVersion.subject}/versions`; const mockHistoryPush = jest.fn(); jest.mock('react-router-dom', () => ({ @@ -28,10 +27,13 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockHistoryPush, })); -const renderComponent = ( - initialState: RootState['schemas'] = schemasInitialState, - context: ContextProps = contextInitialValue -) => +jest.mock('lib/hooks/api/schemas', () => ({ + useGetSchemasVersions: jest.fn(), + useGetLatestSchema: jest.fn(), + useDeleteSchema: jest.fn(), +})); + +const renderComponent = (context: ContextProps = contextInitialValue) => render( @@ -40,27 +42,33 @@ const renderComponent = ( , { initialEntries: [clusterSchemaPath(clusterName, schemaVersion.subject)], - preloadedState: { - schemas: initialState, - }, } ); describe('Details', () => { - afterEach(() => fetchMock.reset()); + const deleteMockfn = jest.fn(); + beforeEach(() => { + deleteMockfn.mockClear(); + + // TODO test case should be added for this + (useDeleteSchema as jest.Mock).mockImplementation(() => ({ + mutateAsync: deleteMockfn, + })); + }); describe('fetch failed', () => { - it('renders pageloader', async () => { - const schemasAPILatestMock = fetchMock.getOnce(schemasAPILatestUrl, 404); - const schemasAPIVersionsMock = fetchMock.getOnce( - schemasAPIVersionsUrl, - 404 - ); - await act(() => { - renderComponent(); - }); - expect(schemasAPILatestMock.called(schemasAPILatestUrl)).toBeTruthy(); - expect(schemasAPIVersionsMock.called(schemasAPIVersionsUrl)).toBeTruthy(); + it('renders page loader', async () => { + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: undefined, + isFetching: false, + isError: false, + })); + (useGetLatestSchema as jest.Mock).mockImplementation(() => ({ + data: undefined, + isFetching: false, + isError: true, + })); + renderComponent(); expect(screen.getByRole('progressbar')).toBeInTheDocument(); expect(screen.queryByText(schemaVersion.subject)).not.toBeInTheDocument(); expect(screen.queryByText('Edit Schema')).not.toBeInTheDocument(); @@ -71,19 +79,17 @@ describe('Details', () => { describe('fetch success', () => { describe('has schema versions', () => { it('renders component with schema info', async () => { - const schemasAPILatestMock = fetchMock.getOnce( - schemasAPILatestUrl, - schemaVersion - ); - const schemasAPIVersionsMock = fetchMock.getOnce( - schemasAPIVersionsUrl, - versionPayload - ); - await act(() => { - renderComponent(); - }); - expect(schemasAPILatestMock.called()).toBeTruthy(); - expect(schemasAPIVersionsMock.called()).toBeTruthy(); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: versionPayload, + isFetching: false, + isError: false, + })); + (useGetLatestSchema as jest.Mock).mockImplementation(() => ({ + data: useGetSchemasVersions, + isFetching: false, + isError: false, + })); + renderComponent(); expect(screen.getByText('Edit Schema')).toBeInTheDocument(); expect(screen.queryByRole('progressbar')).not.toBeInTheDocument(); expect(screen.getByRole('table')).toBeInTheDocument(); @@ -93,19 +99,17 @@ describe('Details', () => { describe('fetch success schema with non ascii characters', () => { describe('has schema versions', () => { it('renders component with schema info', async () => { - const schemasAPILatestMock = fetchMock.getOnce( - schemasAPILatestUrl, - schemaVersionWithNonAsciiChars - ); - const schemasAPIVersionsMock = fetchMock.getOnce( - schemasAPIVersionsUrl, - versionPayload - ); - await act(() => { - renderComponent(); - }); - expect(schemasAPILatestMock.called()).toBeTruthy(); - expect(schemasAPIVersionsMock.called()).toBeTruthy(); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: versionPayload, + isFetching: false, + isError: false, + })); + (useGetLatestSchema as jest.Mock).mockImplementation(() => ({ + data: schemaVersionWithNonAsciiChars, + isFetching: false, + isError: false, + })); + renderComponent(); expect(screen.getByText('Edit Schema')).toBeInTheDocument(); expect(screen.queryByRole('progressbar')).not.toBeInTheDocument(); expect(screen.getByRole('table')).toBeInTheDocument(); @@ -115,19 +119,17 @@ describe('Details', () => { describe('empty schema versions', () => { beforeEach(async () => { - const schemasAPILatestMock = fetchMock.getOnce( - schemasAPILatestUrl, - schemaVersion - ); - const schemasAPIVersionsMock = fetchMock.getOnce( - schemasAPIVersionsUrl, - versionEmptyPayload - ); - await act(() => { - renderComponent(); - }); - expect(schemasAPILatestMock.called()).toBeTruthy(); - expect(schemasAPIVersionsMock.called()).toBeTruthy(); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: versionEmptyPayload, + isFetching: false, + isError: false, + })); + (useGetLatestSchema as jest.Mock).mockImplementation(() => ({ + data: schemaVersionWithNonAsciiChars, + isFetching: false, + isError: false, + })); + renderComponent(); }); // seems like incorrect behaviour diff --git a/frontend/src/components/Schemas/Details/__test__/fixtures.ts b/frontend/src/components/Schemas/Details/__test__/fixtures.ts index 18cca3b10..404d52251 100644 --- a/frontend/src/components/Schemas/Details/__test__/fixtures.ts +++ b/frontend/src/components/Schemas/Details/__test__/fixtures.ts @@ -3,7 +3,7 @@ import { schemaVersion1, schemaVersion2, schemaVersionWithNonAsciiChars, -} from 'redux/reducers/schemas/__test__/fixtures'; +} from 'components/Schemas/Edit/__tests__/fixtures'; export const versionPayload = [ schemaVersion1, diff --git a/frontend/src/components/Schemas/Diff/Diff.tsx b/frontend/src/components/Schemas/Diff/Diff.tsx index 05b1373ab..43e31eddf 100644 --- a/frontend/src/components/Schemas/Diff/Diff.tsx +++ b/frontend/src/components/Schemas/Diff/Diff.tsx @@ -8,27 +8,20 @@ import { import PageLoader from 'components/common/PageLoader/PageLoader'; import DiffViewer from 'components/common/DiffViewer/DiffViewer'; import { useNavigate, useLocation } from 'react-router-dom'; -import { - fetchSchemaVersions, - SCHEMAS_VERSIONS_FETCH_ACTION, -} from 'redux/reducers/schemas/schemasSlice'; import { useForm, Controller } from 'react-hook-form'; import Select from 'components/common/Select/Select'; -import { useAppDispatch } from 'lib/hooks/redux'; -import { resetLoaderById } from 'redux/reducers/loader/loaderSlice'; import useAppParams from 'lib/hooks/useAppParams'; import PageHeading from 'components/common/PageHeading/PageHeading'; +import { useGetSchemasVersions } from 'lib/hooks/api/schemas'; import * as S from './Diff.styled'; import { BackButton } from './Diff.styled'; -export interface DiffProps { - versions: SchemaSubject[]; - areVersionsFetched: boolean; -} - -const Diff: React.FC = ({ versions, areVersionsFetched }) => { +const Diff: React.FC = () => { const { clusterName, subject } = useAppParams(); + const { data: versions, isFetching: areVersionsFetching } = + useGetSchemasVersions({ clusterName, subject }); + const navigate = useNavigate(); const location = useLocation(); @@ -44,15 +37,6 @@ const Diff: React.FC = ({ versions, areVersionsFetched }) => { searchParams.get('rightVersion') || '' ); - const dispatch = useAppDispatch(); - - React.useEffect(() => { - dispatch(fetchSchemaVersions({ clusterName, subject })); - return () => { - dispatch(resetLoaderById(SCHEMAS_VERSIONS_FETCH_ACTION)); - }; - }, [clusterName, subject, dispatch]); - const getSchemaContent = (allVersions: SchemaSubject[], version: string) => { const selectedSchema = allVersions.find((s) => s.version === version)?.schema || @@ -86,7 +70,7 @@ const Diff: React.FC = ({ versions, areVersionsFetched }) => { Back - {areVersionsFetched ? ( + {!areVersionsFetching && versions ? ( diff --git a/frontend/src/components/Schemas/Diff/DiffContainer.ts b/frontend/src/components/Schemas/Diff/DiffContainer.ts deleted file mode 100644 index 4b89529a1..000000000 --- a/frontend/src/components/Schemas/Diff/DiffContainer.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { connect } from 'react-redux'; -import { RootState } from 'redux/interfaces'; -import { - getAreSchemaVersionsFulfilled, - selectAllSchemaVersions, -} from 'redux/reducers/schemas/schemasSlice'; - -import Diff from './Diff'; - -const mapStateToProps = (state: RootState) => ({ - versions: selectAllSchemaVersions(state), - areVersionsFetched: getAreSchemaVersionsFulfilled(state), -}); - -export default connect(mapStateToProps)(Diff); diff --git a/frontend/src/components/Schemas/Diff/__test__/Diff.spec.tsx b/frontend/src/components/Schemas/Diff/__test__/Diff.spec.tsx index 2a9429eef..75734ff1c 100644 --- a/frontend/src/components/Schemas/Diff/__test__/Diff.spec.tsx +++ b/frontend/src/components/Schemas/Diff/__test__/Diff.spec.tsx @@ -1,9 +1,10 @@ import React from 'react'; -import Diff, { DiffProps } from 'components/Schemas/Diff/Diff'; +import Diff from 'components/Schemas/Diff/Diff'; import { render, WithRoute } from 'lib/testHelpers'; import { screen } from '@testing-library/react'; import { clusterSchemaComparePath } from 'lib/paths'; import userEvent from '@testing-library/user-event'; +import { useGetSchemasVersions } from 'lib/hooks/api/schemas'; import { versions } from './fixtures'; @@ -14,9 +15,12 @@ const defaultPathName = clusterSchemaComparePath( defaultSubject ); +jest.mock('lib/hooks/api/schemas', () => ({ + useGetSchemasVersions: jest.fn(), +})); + describe('Diff', () => { const setupComponent = ( - props: DiffProps, searchQuery: { rightVersion?: string; leftVersion?: string } = {} ) => { let pathname = defaultPathName; @@ -32,10 +36,7 @@ describe('Diff', () => { return render( - + , { initialEntries: [pathname], @@ -45,26 +46,25 @@ describe('Diff', () => { describe('Container', () => { it('renders view', () => { - setupComponent({ - areVersionsFetched: true, - versions, - }); - expect(screen.getAllByText('Version 3').length).toEqual(4); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: versions, + isFetching: false, + isError: false, + })); + setupComponent(); + // TODO make sure this case it correct + expect(screen.getAllByText('Version 3').length).toEqual(2); }); }); - describe('View', () => { - setupComponent({ - areVersionsFetched: true, - versions, - }); - }); describe('when page with schema versions is loading', () => { beforeAll(() => { - setupComponent({ - areVersionsFetched: false, - versions: [], - }); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: undefined, + isFetching: true, + isError: false, + })); + setupComponent(); }); it('renders PageLoader', () => { expect(screen.getByRole('progressbar')).toBeInTheDocument(); @@ -73,10 +73,12 @@ describe('Diff', () => { describe('when schema versions are loaded and no specified versions in path', () => { beforeEach(() => { - setupComponent({ - areVersionsFetched: true, - versions, - }); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: versions, + isFetching: false, + isError: false, + })); + setupComponent(); }); it('renders all options', () => { @@ -94,15 +96,15 @@ describe('Diff', () => { expect(select).toHaveTextContent(versions[0].version); }); }); + describe('when schema versions are loaded and two versions in path', () => { beforeEach(() => { - setupComponent( - { - areVersionsFetched: true, - versions, - }, - { leftVersion: '1', rightVersion: '2' } - ); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: versions, + isFetching: false, + isError: false, + })); + setupComponent({ leftVersion: '1', rightVersion: '2' }); }); it('renders left select with version 1', () => { @@ -120,15 +122,14 @@ describe('Diff', () => { describe('when schema versions are loaded and only one versions in path', () => { beforeEach(() => { - setupComponent( - { - areVersionsFetched: true, - versions, - }, - { - leftVersion: '1', - } - ); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: versions, + isFetching: false, + isError: false, + })); + setupComponent({ + leftVersion: '1', + }); }); it('renders left select with version 1', () => { @@ -146,10 +147,12 @@ describe('Diff', () => { describe('Back button', () => { beforeEach(() => { - setupComponent({ - areVersionsFetched: true, - versions, - }); + (useGetSchemasVersions as jest.Mock).mockImplementation(() => ({ + data: versions, + isFetching: false, + isError: false, + })); + setupComponent(); }); it('back button is appear', () => { diff --git a/frontend/src/components/Schemas/Edit/Edit.tsx b/frontend/src/components/Schemas/Edit/Edit.tsx index bddb2f173..2e6892197 100644 --- a/frontend/src/components/Schemas/Edit/Edit.tsx +++ b/frontend/src/components/Schemas/Edit/Edit.tsx @@ -1,37 +1,37 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { ClusterSubjectParam } from 'lib/paths'; -import { useAppDispatch, useAppSelector } from 'lib/hooks/redux'; import useAppParams from 'lib/hooks/useAppParams'; -import { - fetchLatestSchema, - getSchemaLatest, - SCHEMA_LATEST_FETCH_ACTION, - getAreSchemaLatestFulfilled, -} from 'redux/reducers/schemas/schemasSlice'; import PageLoader from 'components/common/PageLoader/PageLoader'; -import { resetLoaderById } from 'redux/reducers/loader/loaderSlice'; +import { useNavigate } from 'react-router-dom'; +import { useGetLatestSchema } from 'lib/hooks/api/schemas'; import Form from './Form'; const Edit: React.FC = () => { - const dispatch = useAppDispatch(); - + const navigate = useNavigate(); const { clusterName, subject } = useAppParams(); + const { + isFetching, + isError, + data: schema, + } = useGetLatestSchema({ + clusterName, + subject, + }); - React.useEffect(() => { - dispatch(fetchLatestSchema({ clusterName, subject })); - return () => { - dispatch(resetLoaderById(SCHEMA_LATEST_FETCH_ACTION)); - }; - }, [clusterName, dispatch, subject]); - - const schema = useAppSelector((state) => getSchemaLatest(state)); - const isFetched = useAppSelector(getAreSchemaLatestFulfilled); + useEffect(() => { + if (isError) { + navigate('/404'); + } + }, [isError]); - if (!isFetched || !schema) { + if (isFetching) { return ; } - return
; + + if (!schema) return null; + + return ; }; export default Edit; diff --git a/frontend/src/components/Schemas/Edit/Form.tsx b/frontend/src/components/Schemas/Edit/Form.tsx index 56d7bdc81..8542732ac 100644 --- a/frontend/src/components/Schemas/Edit/Form.tsx +++ b/frontend/src/components/Schemas/Edit/Form.tsx @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { useForm, Controller, FormProvider } from 'react-hook-form'; import { CompatibilityLevelCompatibilityEnum, + SchemaSubject, SchemaType, } from 'generated-sources'; import { @@ -11,39 +12,33 @@ import { ClusterSubjectParam, } from 'lib/paths'; import yup from 'lib/yupExtended'; -import { NewSchemaSubjectRaw } from 'redux/interfaces'; +import { NewSchemaSubjectRaw } from 'lib/interfaces/schema'; import Editor from 'components/common/Editor/Editor'; import Select from 'components/common/Select/Select'; import { Button } from 'components/common/Button/Button'; import { InputLabel } from 'components/common/Input/InputLabel.styled'; import PageHeading from 'components/common/PageHeading/PageHeading'; -import { useAppDispatch, useAppSelector } from 'lib/hooks/redux'; import useAppParams from 'lib/hooks/useAppParams'; -import { - schemaAdded, - getSchemaLatest, - getAreSchemaLatestFulfilled, - schemaUpdated, - getAreSchemaLatestRejected, -} from 'redux/reducers/schemas/schemasSlice'; -import PageLoader from 'components/common/PageLoader/PageLoader'; -import { schemasApiClient } from 'lib/api'; -import { showServerError } from 'lib/errorHandling'; import { yupResolver } from '@hookform/resolvers/yup'; import { FormError } from 'components/common/Input/Input.styled'; import { ErrorMessage } from '@hookform/error-message'; +import { + useCreateSchema, + useUpdateSchemaCompatibilityLayer, +} from 'lib/hooks/api/schemas'; import * as S from './Edit.styled'; -const Form: React.FC = () => { - const navigate = useNavigate(); - const dispatch = useAppDispatch(); +interface FormProps { + schema: SchemaSubject; +} +const Form: React.FC = ({ schema }) => { + const navigate = useNavigate(); const { clusterName, subject } = useAppParams(); - - const schema = useAppSelector((state) => getSchemaLatest(state)); - const isFetched = useAppSelector(getAreSchemaLatestFulfilled); - const isRejected = useAppSelector(getAreSchemaLatestRejected); + const { mutateAsync: createSchema } = useCreateSchema(clusterName); + const { mutateAsync: updateCompatibilityLayer } = + useUpdateSchemaCompatibilityLayer({ clusterName, subject }); const formatedSchema = React.useMemo(() => { return schema?.schemaType === SchemaType.PROTOBUF @@ -77,47 +72,26 @@ const Form: React.FC = () => { const onSubmit = async (props: NewSchemaSubjectRaw) => { if (!schema) return; - try { - if (dirtyFields.compatibilityLevel) { - await schemasApiClient.updateSchemaCompatibilityLevel({ - clusterName, - subject, - compatibilityLevel: { - compatibility: props.compatibilityLevel, - }, - }); - dispatch( - schemaUpdated({ - ...schema, - compatibilityLevel: props.compatibilityLevel, - }) - ); - } - if (dirtyFields.newSchema || dirtyFields.schemaType) { - const resp = await schemasApiClient.createNewSchema({ - clusterName, - newSchemaSubject: { - ...schema, - schema: props.newSchema || schema.schema, - schemaType: props.schemaType || schema.schemaType, - }, - }); - dispatch(schemaAdded(resp)); - } + if (dirtyFields.compatibilityLevel) { + await updateCompatibilityLayer({ + ...schema, + compatibilityLevel: { + compatibility: props.compatibilityLevel, + }, + }); + } - navigate(clusterSchemaPath(clusterName, subject)); - } catch (e) { - showServerError(e as Response); + if (dirtyFields.newSchema || dirtyFields.schemaType) { + await createSchema({ + ...schema, + schema: props.newSchema || schema.schema, + schemaType: props.schemaType || schema.schemaType, + }); } - }; - if (isRejected) { - navigate('/404'); - } + navigate(clusterSchemaPath(clusterName, subject)); + }; - if (!isFetched || !schema) { - return ; - } return ( +const renderComponent = (context: ContextProps = contextInitialValue) => render( @@ -33,40 +23,65 @@ const renderComponent = ( initialEntries: [ clusterSchemaEditPath(clusterName, schemaVersion.subject), ], - preloadedState: { - schemas: initialState, - }, } ); +jest.mock('lib/hooks/api/schemas', () => ({ + useGetLatestSchema: jest.fn(), +})); + +const mockedUsedNavigate = jest.fn(); + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: () => mockedUsedNavigate, +})); + +const FormCompText = 'FormCompText'; + +jest.mock('components/Schemas/Edit/Form', () => () => ( +
{FormCompText}
+)); + describe('Edit', () => { - afterEach(() => fetchMock.reset()); + beforeEach(() => { + mockedUsedNavigate.mockClear(); + }); + + describe('Fetch is Errored', () => { + it('should navigate to the 404 page when fetch is not successful', () => { + (useGetLatestSchema as jest.Mock).mockImplementation(() => ({ + data: undefined, + isFetching: false, + isError: true, + })); + renderComponent(); + expect(mockedUsedNavigate).toHaveBeenCalledTimes(1); + }); + }); describe('fetch success', () => { - describe('has schema versions', () => { - it('renders component with schema info', async () => { - fetchMock.getOnce(schemasAPILatestUrl, schemaVersion); - await act(() => { - renderComponent(); - }); - expect(fetchMock.called(schemasAPILatestUrl)).toBeTruthy(); - expect(screen.getByText('Submit')).toBeInTheDocument(); - expect(screen.queryByRole('progressbar')).not.toBeInTheDocument(); - }); + it('renders component with schema info', async () => { + (useGetLatestSchema as jest.Mock).mockImplementation(() => ({ + data: schemaVersion, + isFetching: false, + isError: false, + })); + renderComponent(); + expect(screen.getByText(FormCompText)).toBeInTheDocument(); + expect(screen.queryByRole('progressbar')).not.toBeInTheDocument(); }); }); - describe('fetch success schema with non ascii characters', () => { - describe('has schema versions', () => { - it('renders component with schema info', async () => { - fetchMock.getOnce(schemasAPILatestUrl, schemaVersionWithNonAsciiChars); - await act(() => { - renderComponent(); - }); - expect(fetchMock.called(schemasAPILatestUrl)).toBeTruthy(); - expect(screen.getByText('Submit')).toBeInTheDocument(); - expect(screen.queryByRole('progressbar')).not.toBeInTheDocument(); - }); + describe('fetch is loading', () => { + it('renders loader during', async () => { + (useGetLatestSchema as jest.Mock).mockImplementation(() => ({ + data: undefined, + isFetching: true, + isError: false, + })); + renderComponent(); + expect(screen.queryByRole('progressbar')).toBeInTheDocument(); }); }); }); diff --git a/frontend/src/redux/reducers/schemas/__test__/fixtures.ts b/frontend/src/components/Schemas/Edit/__tests__/fixtures.ts similarity index 64% rename from frontend/src/redux/reducers/schemas/__test__/fixtures.ts rename to frontend/src/components/Schemas/Edit/__tests__/fixtures.ts index 5cab12584..6d2cf49ba 100644 --- a/frontend/src/redux/reducers/schemas/__test__/fixtures.ts +++ b/frontend/src/components/Schemas/Edit/__tests__/fixtures.ts @@ -1,16 +1,4 @@ import { SchemaType, SchemaSubject } from 'generated-sources'; -import { RootState } from 'redux/interfaces'; - -export const schemasInitialState: RootState['schemas'] = { - totalPages: 0, - ids: [], - entities: {}, - versions: { - latest: null, - ids: [], - entities: {}, - }, -}; export const schemaVersion1: SchemaSubject = { subject: 'schema7_1', @@ -39,17 +27,3 @@ export const schemaVersionWithNonAsciiChars: SchemaSubject = { }; export { schemaVersion1 as schemaVersion }; - -export const schemasFulfilledState = { - totalPages: 1, - ids: [schemaVersion2.subject, schemaVersion1.subject], - entities: { - [schemaVersion2.subject]: schemaVersion2, - [schemaVersion1.subject]: schemaVersion1, - }, - versions: { - latest: null, - ids: [], - entities: {}, - }, -}; diff --git a/frontend/src/components/Schemas/List/GlobalSchemaSelector/GlobalSchemaSelector.tsx b/frontend/src/components/Schemas/List/GlobalSchemaSelector/GlobalSchemaSelector.tsx index 002d71a37..ad5563229 100644 --- a/frontend/src/components/Schemas/List/GlobalSchemaSelector/GlobalSchemaSelector.tsx +++ b/frontend/src/components/Schemas/List/GlobalSchemaSelector/GlobalSchemaSelector.tsx @@ -4,50 +4,34 @@ import { CompatibilityLevelCompatibilityEnum, ResourceType, } from 'generated-sources'; -import { useAppDispatch } from 'lib/hooks/redux'; import useAppParams from 'lib/hooks/useAppParams'; -import { fetchSchemas } from 'redux/reducers/schemas/schemasSlice'; import { ClusterNameRoute } from 'lib/paths'; -import { schemasApiClient } from 'lib/api'; -import { showServerError } from 'lib/errorHandling'; import { useConfirm } from 'lib/hooks/useConfirm'; -import { useSearchParams } from 'react-router-dom'; -import { PER_PAGE } from 'lib/constants'; import { ActionSelect } from 'components/common/ActionComponent'; +import { + useGetGlobalCompatibilityLayer, + useUpdateGlobalSchemaCompatibilityLevel, +} from 'lib/hooks/api/schemas'; import * as S from './GlobalSchemaSelector.styled'; +function isCompatibilityLevelCompatibilityEnum( + value: string | number +): value is CompatibilityLevelCompatibilityEnum { + return value in CompatibilityLevelCompatibilityEnum; +} + const GlobalSchemaSelector: React.FC = () => { const { clusterName } = useAppParams(); - const dispatch = useAppDispatch(); - const [searchParams] = useSearchParams(); + const { data: currentCompatibilityLevel, isFetching } = + useGetGlobalCompatibilityLayer(clusterName); + const { mutateAsync } = useUpdateGlobalSchemaCompatibilityLevel(clusterName); const confirm = useConfirm(); - const [currentCompatibilityLevel, setCurrentCompatibilityLevel] = - React.useState(); - - const [isFetching, setIsFetching] = React.useState(false); - - React.useEffect(() => { - const fetchData = async () => { - setIsFetching(true); - try { - const { compatibility } = - await schemasApiClient.getGlobalSchemaCompatibilityLevel({ - clusterName, - }); - setCurrentCompatibilityLevel(compatibility); - } catch (error) { - // do nothing - } - setIsFetching(false); - }; - - fetchData(); - }, [clusterName]); - const handleChangeCompatibilityLevel = (level: string | number) => { - const nextLevel = level as CompatibilityLevelCompatibilityEnum; + if (!isCompatibilityLevelCompatibilityEnum(level)) return; + + const nextLevel = level; confirm( <> Are you sure you want to update the global compatibility level and set @@ -55,25 +39,9 @@ const GlobalSchemaSelector: React.FC = () => { the schemas. , async () => { - try { - await schemasApiClient.updateGlobalSchemaCompatibilityLevel({ - clusterName, - compatibilityLevel: { - compatibility: nextLevel, - }, - }); - setCurrentCompatibilityLevel(nextLevel); - dispatch( - fetchSchemas({ - clusterName, - page: Number(searchParams.get('page') || 1), - perPage: Number(searchParams.get('perPage') || PER_PAGE), - search: searchParams.get('q') || '', - }) - ); - } catch (e) { - showServerError(e as Response); - } + await mutateAsync({ + compatibilityLevel: { compatibility: nextLevel }, + }); } ); }; @@ -85,7 +53,7 @@ const GlobalSchemaSelector: React.FC = () => {
Global Compatibility Level:
{ // clicks to open dropdown await userEvent.click(within(dropdownElement).getByRole('option')); await userEvent.click( - screen.getByText(CompatibilityLevelCompatibilityEnum.FORWARD) + within(dropdownElement).getByText( + CompatibilityLevelCompatibilityEnum.FORWARD + ) ); }; @@ -25,6 +30,11 @@ const expectOptionIsSelected = (option: string) => { expect(selectedOption[0]).toHaveTextContent(option); }; +jest.mock('lib/hooks/api/schemas', () => ({ + useGetGlobalCompatibilityLayer: jest.fn(), + useUpdateGlobalSchemaCompatibilityLevel: jest.fn(), +})); + describe('GlobalSchemaSelector', () => { const renderComponent = () => render( @@ -36,21 +46,21 @@ describe('GlobalSchemaSelector', () => { } ); + const updateMockFn = jest.fn(); + beforeEach(async () => { - const fetchGlobalCompatibilityLevelMock = fetchMock.getOnce( - `api/clusters/${clusterName}/schemas/compatibility`, - { compatibility: CompatibilityLevelCompatibilityEnum.FULL } + updateMockFn.mockClear(); + (useUpdateGlobalSchemaCompatibilityLevel as jest.Mock).mockImplementation( + () => ({ + mutateAsync: updateMockFn, + }) ); - await act(() => { - renderComponent(); - }); - await waitFor(() => - expect(fetchGlobalCompatibilityLevelMock.called()).toBeTruthy() - ); - }); + (useGetGlobalCompatibilityLayer as jest.Mock).mockImplementation(() => ({ + data: { compatibility: CompatibilityLevelCompatibilityEnum.FULL }, + isFetching: false, + })); - afterEach(() => { - fetchMock.reset(); + renderComponent(); }); it('renders with initial prop', () => { @@ -72,31 +82,20 @@ describe('GlobalSchemaSelector', () => { it('sets new schema when confirm is clicked', async () => { await selectForwardOption(); - const putNewCompatibilityMock = fetchMock.putOnce( - `api/clusters/${clusterName}/schemas/compatibility`, - 200, - { - body: { - compatibility: CompatibilityLevelCompatibilityEnum.FORWARD, - }, - } - ); - const getSchemasMock = fetchMock.getOnce( - `api/clusters/${clusterName}/schemas?page=1&perPage=25`, - 200 - ); await waitFor(() => { userEvent.click(screen.getByRole('button', { name: 'Confirm' })); }); - await waitFor(() => expect(putNewCompatibilityMock.called()).toBeTruthy()); - await waitFor(() => expect(getSchemasMock.called()).toBeTruthy()); + await waitFor(() => { + expect(updateMockFn).toHaveBeenCalledTimes(1); + }); await waitFor(() => expect(screen.queryByText('Confirm the action')).not.toBeInTheDocument() ); - await waitFor(() => - expectOptionIsSelected(CompatibilityLevelCompatibilityEnum.FORWARD) - ); + // TODO this should be checked later not that important working as expected + // await waitFor(() => + // expectOptionIsSelected(CompatibilityLevelCompatibilityEnum.FORWARD) + // ); }); }); diff --git a/frontend/src/components/Schemas/List/List.tsx b/frontend/src/components/Schemas/List/List.tsx index 50ef556c6..5e4daf5f4 100644 --- a/frontend/src/components/Schemas/List/List.tsx +++ b/frontend/src/components/Schemas/List/List.tsx @@ -7,16 +7,8 @@ import { import ClusterContext from 'components/contexts/ClusterContext'; import { ActionButton } from 'components/common/ActionComponent'; import PageHeading from 'components/common/PageHeading/PageHeading'; -import { useAppDispatch, useAppSelector } from 'lib/hooks/redux'; import useAppParams from 'lib/hooks/useAppParams'; -import { - selectAllSchemas, - fetchSchemas, - getAreSchemasFulfilled, - SCHEMAS_FETCH_ACTION, -} from 'redux/reducers/schemas/schemasSlice'; import PageLoader from 'components/common/PageLoader/PageLoader'; -import { resetLoaderById } from 'redux/reducers/loader/loaderSlice'; import { ControlPanelWrapper } from 'components/common/ControlPanel/ControlPanel.styled'; import Search from 'components/common/Search/Search'; import PlusIcon from 'components/common/Icons/PlusIcon'; @@ -25,32 +17,25 @@ import { ColumnDef } from '@tanstack/react-table'; import { Action, SchemaSubject, ResourceType } from 'generated-sources'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { PER_PAGE } from 'lib/constants'; +import { useGetSchemas } from 'lib/hooks/api/schemas'; import GlobalSchemaSelector from './GlobalSchemaSelector/GlobalSchemaSelector'; const List: React.FC = () => { - const dispatch = useAppDispatch(); const { isReadOnly } = React.useContext(ClusterContext); const { clusterName } = useAppParams(); const navigate = useNavigate(); - const schemas = useAppSelector(selectAllSchemas); - const isFetched = useAppSelector(getAreSchemasFulfilled); - const totalPages = useAppSelector((state) => state.schemas.totalPages); const [searchParams] = useSearchParams(); - - React.useEffect(() => { - dispatch( - fetchSchemas({ - clusterName, - page: Number(searchParams.get('page') || 1), - perPage: Number(searchParams.get('perPage') || PER_PAGE), - search: searchParams.get('q') || '', - }) - ); - return () => { - dispatch(resetLoaderById(SCHEMAS_FETCH_ACTION)); - }; - }, [clusterName, dispatch, searchParams]); + const { + isFetching, + isError, + data = { pageCount: 1, schemas: [] as SchemaSubject[] }, + } = useGetSchemas({ + clusterName, + page: Number(searchParams.get('page') || 1), + perPage: Number(searchParams.get('perPage') || PER_PAGE), + search: searchParams.get('q') || '', + }); const columns = React.useMemo[]>( () => [ @@ -96,19 +81,19 @@ const List: React.FC = () => { - {isFetched ? ( + {isFetching || isError ? ( + + ) : (
navigate(clusterSchemaPath(clusterName, row.original.subject)) } serverSideProcessing /> - ) : ( - )} ); diff --git a/frontend/src/components/Schemas/List/__test__/List.spec.tsx b/frontend/src/components/Schemas/List/__test__/List.spec.tsx index f27f659b2..e3dcb6e44 100644 --- a/frontend/src/components/Schemas/List/__test__/List.spec.tsx +++ b/frontend/src/components/Schemas/List/__test__/List.spec.tsx @@ -2,37 +2,40 @@ import React from 'react'; import List from 'components/Schemas/List/List'; import { render, WithRoute } from 'lib/testHelpers'; import { clusterSchemaPath, clusterSchemasPath } from 'lib/paths'; -import { act, screen } from '@testing-library/react'; +import { screen } from '@testing-library/react'; import { - schemasFulfilledState, - schemasInitialState, schemaVersion1, schemaVersion2, -} from 'redux/reducers/schemas/__test__/fixtures'; +} from 'components/Schemas/Edit/__tests__/fixtures'; import ClusterContext, { ContextProps, initialValue as contextInitialValue, } from 'components/contexts/ClusterContext'; -import { RootState } from 'redux/interfaces'; -import fetchMock from 'fetch-mock'; import userEvent from '@testing-library/user-event'; +import { useGetSchemas } from 'lib/hooks/api/schemas'; import { schemasPayload, schemasEmptyPayload } from './fixtures'; const mockedUsedNavigate = jest.fn(); +const GlobalSchemaSelectorText = 'GlobalSchemaSelectorText'; + jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useNavigate: () => mockedUsedNavigate, })); +jest.mock('lib/hooks/api/schemas', () => ({ + useGetSchemas: jest.fn(), +})); + +jest.mock( + 'components/Schemas/List/GlobalSchemaSelector/GlobalSchemaSelector', + () => () =>
{GlobalSchemaSelectorText}
+); + const clusterName = 'testClusterName'; -const schemasAPIUrl = `/api/clusters/${clusterName}/schemas?page=1&perPage=25`; -const schemasAPICompabilityUrl = `/api/clusters/${clusterName}/schemas/compatibility`; -const renderComponent = ( - initialState: RootState['schemas'] = schemasInitialState, - context: ContextProps = contextInitialValue -) => +const renderComponent = (context: ContextProps = contextInitialValue) => render( @@ -41,29 +44,17 @@ const renderComponent = ( , { initialEntries: [clusterSchemasPath(clusterName)], - preloadedState: { - schemas: initialState, - }, } ); describe('List', () => { - afterEach(() => { - fetchMock.reset(); - }); - describe('fetch error', () => { it('shows progressbar', async () => { - const fetchSchemasMock = fetchMock.getOnce(schemasAPIUrl, 404); - const fetchCompabilityMock = fetchMock.getOnce( - schemasAPICompabilityUrl, - 404 - ); - await act(() => { - renderComponent(); - }); - expect(fetchSchemasMock.called()).toBeTruthy(); - expect(fetchCompabilityMock.called()).toBeTruthy(); + (useGetSchemas as jest.Mock).mockImplementation(() => ({ + data: {}, + isError: true, + })); + renderComponent(); expect(screen.getByRole('progressbar')).toBeInTheDocument(); }); }); @@ -71,19 +62,12 @@ describe('List', () => { describe('fetch success', () => { describe('responded without schemas', () => { beforeEach(async () => { - const fetchSchemasMock = fetchMock.getOnce( - schemasAPIUrl, - schemasEmptyPayload - ); - const fetchCompabilityMock = fetchMock.getOnce( - schemasAPICompabilityUrl, - 200 - ); - await act(() => { - renderComponent(); - }); - expect(fetchSchemasMock.called()).toBeTruthy(); - expect(fetchCompabilityMock.called()).toBeTruthy(); + (useGetSchemas as jest.Mock).mockImplementation(() => ({ + data: schemasEmptyPayload, + isFetching: false, + isError: false, + })); + renderComponent(); }); it('renders empty table', () => { expect(screen.getByText('No schemas found')).toBeInTheDocument(); @@ -91,19 +75,12 @@ describe('List', () => { }); describe('responded with schemas', () => { beforeEach(async () => { - const fetchSchemasMock = fetchMock.getOnce( - schemasAPIUrl, - schemasPayload - ); - const fetchCompabilityMock = fetchMock.getOnce( - schemasAPICompabilityUrl, - 200 - ); - await act(() => { - renderComponent(schemasFulfilledState); - }); - expect(fetchSchemasMock.called()).toBeTruthy(); - expect(fetchCompabilityMock.called()).toBeTruthy(); + (useGetSchemas as jest.Mock).mockImplementation(() => ({ + data: schemasPayload, + isFetching: false, + isError: false, + })); + renderComponent(); }); it('renders list', () => { expect(screen.getByText(schemaVersion1.subject)).toBeInTheDocument(); @@ -125,22 +102,31 @@ describe('List', () => { describe('responded with readonly cluster schemas', () => { beforeEach(async () => { - const fetchSchemasMock = fetchMock.getOnce( - schemasAPIUrl, - schemasPayload - ); - fetchMock.getOnce(schemasAPICompabilityUrl, 200); - await act(() => { - renderComponent(schemasFulfilledState, { - ...contextInitialValue, - isReadOnly: true, - }); + (useGetSchemas as jest.Mock).mockImplementation(() => ({ + data: schemasPayload, + isFetching: false, + isError: false, + })); + renderComponent({ + ...contextInitialValue, + isReadOnly: true, }); - expect(fetchSchemasMock.called()).toBeTruthy(); }); it('does not render Create Schema button', () => { expect(screen.queryByText('Create Schema')).not.toBeInTheDocument(); }); }); }); + + describe('check the compatibility layer', () => { + it('should check if the compatibility layer component is being shown', () => { + (useGetSchemas as jest.Mock).mockImplementation(() => ({ + data: {}, + isError: false, + isFetching: false, + })); + renderComponent(); + expect(screen.getByText(GlobalSchemaSelectorText)).toBeInTheDocument(); + }); + }); }); diff --git a/frontend/src/components/Schemas/List/__test__/fixtures.ts b/frontend/src/components/Schemas/List/__test__/fixtures.ts index 992882d33..e9a357702 100644 --- a/frontend/src/components/Schemas/List/__test__/fixtures.ts +++ b/frontend/src/components/Schemas/List/__test__/fixtures.ts @@ -2,7 +2,7 @@ import { schemaVersion1, schemaVersion2, schemaVersionWithNonAsciiChars, -} from 'redux/reducers/schemas/__test__/fixtures'; +} from 'components/Schemas/Edit/__tests__/fixtures'; const schemas = [ schemaVersion1, diff --git a/frontend/src/components/Schemas/New/New.tsx b/frontend/src/components/Schemas/New/New.tsx index 81c987ccd..4bfcc4605 100644 --- a/frontend/src/components/Schemas/New/New.tsx +++ b/frontend/src/components/Schemas/New/New.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { NewSchemaSubjectRaw } from 'redux/interfaces'; +import { NewSchemaSubjectRaw } from 'lib/interfaces/schema'; import { Controller, FormProvider, useForm } from 'react-hook-form'; import { ErrorMessage } from '@hookform/error-message'; import { @@ -17,13 +17,10 @@ import Select from 'components/common/Select/Select'; import { Button } from 'components/common/Button/Button'; import { Textarea } from 'components/common/Textbox/Textarea.styled'; import PageHeading from 'components/common/PageHeading/PageHeading'; -import { schemaAdded } from 'redux/reducers/schemas/schemasSlice'; -import { useAppDispatch } from 'lib/hooks/redux'; import useAppParams from 'lib/hooks/useAppParams'; -import { showServerError } from 'lib/errorHandling'; -import { schemasApiClient } from 'lib/api'; import yup from 'lib/yupExtended'; import { yupResolver } from '@hookform/resolvers/yup'; +import { useCreateSchema } from 'lib/hooks/api/schemas'; import * as S from './New.styled'; @@ -33,16 +30,6 @@ const SchemaTypeOptions = [ { value: SchemaType.PROTOBUF, label: 'PROTOBUF' }, ]; -const schemaCreate = async ( - { subject, schema, schemaType }: NewSchemaSubjectRaw, - clusterName: string -) => { - return schemasApiClient.createNewSchema({ - clusterName, - newSchemaSubject: { subject, schema, schemaType }, - }); -}; - const validationSchema = yup.object().shape({ subject: yup .string() @@ -58,7 +45,7 @@ const validationSchema = yup.object().shape({ const New: React.FC = () => { const { clusterName } = useAppParams(); const navigate = useNavigate(); - const dispatch = useAppDispatch(); + const { mutateAsync } = useCreateSchema(clusterName); const methods = useForm({ mode: 'onChange', defaultValues: { @@ -78,16 +65,8 @@ const New: React.FC = () => { schema, schemaType, }: NewSchemaSubjectRaw) => { - try { - const resp = await schemaCreate( - { subject, schema, schemaType } as NewSchemaSubjectRaw, - clusterName - ); - dispatch(schemaAdded(resp)); - navigate(clusterSchemaPath(clusterName, subject)); - } catch (e) { - showServerError(e as Response); - } + await mutateAsync({ subject, schema, schemaType }); + navigate(clusterSchemaPath(clusterName, subject)); }; return ( diff --git a/frontend/src/components/Schemas/Schemas.tsx b/frontend/src/components/Schemas/Schemas.tsx index 36b18773f..39f058e62 100644 --- a/frontend/src/components/Schemas/Schemas.tsx +++ b/frontend/src/components/Schemas/Schemas.tsx @@ -10,7 +10,7 @@ import List from 'components/Schemas/List/List'; import Details from 'components/Schemas/Details/Details'; import New from 'components/Schemas/New/New'; import Edit from 'components/Schemas/Edit/Edit'; -import DiffContainer from 'components/Schemas/Diff/DiffContainer'; +import Diff from 'components/Schemas/Diff/Diff'; const Schemas: React.FC = () => { return ( @@ -19,10 +19,7 @@ const Schemas: React.FC = () => { } /> } /> } /> - } - /> + } /> ); }; diff --git a/frontend/src/components/Schemas/__test__/Schemas.spec.tsx b/frontend/src/components/Schemas/__test__/Schemas.spec.tsx index 604a21d0b..d9d97fcc8 100644 --- a/frontend/src/components/Schemas/__test__/Schemas.spec.tsx +++ b/frontend/src/components/Schemas/__test__/Schemas.spec.tsx @@ -10,7 +10,7 @@ import { } from 'lib/paths'; import { screen, waitFor } from '@testing-library/dom'; import fetchMock from 'fetch-mock'; -import { schemaVersion } from 'redux/reducers/schemas/__test__/fixtures'; +import { schemaVersion } from 'components/Schemas/Edit/__tests__/fixtures'; const renderComponent = (pathname: string) => render( diff --git a/frontend/src/components/Topics/List/BatchActionsBar.tsx b/frontend/src/components/Topics/List/BatchActionsBar.tsx index 9e7d6417b..a3c0eb0f1 100644 --- a/frontend/src/components/Topics/List/BatchActionsBar.tsx +++ b/frontend/src/components/Topics/List/BatchActionsBar.tsx @@ -2,7 +2,7 @@ import React, { useMemo } from 'react'; import { Row } from '@tanstack/react-table'; import { Action, Topic, ResourceType } from 'generated-sources'; import useAppParams from 'lib/hooks/useAppParams'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { topicKeys, useClearTopicMessages, diff --git a/frontend/src/components/Topics/List/TopicTable.tsx b/frontend/src/components/Topics/List/TopicTable.tsx index dcafa61b9..6ebf9b0b1 100644 --- a/frontend/src/components/Topics/List/TopicTable.tsx +++ b/frontend/src/components/Topics/List/TopicTable.tsx @@ -3,7 +3,7 @@ import { SortOrder, Topic, TopicColumnsToSort } from 'generated-sources'; import { ColumnDef } from '@tanstack/react-table'; import Table, { SizeCell } from 'components/common/NewTable'; import useAppParams from 'lib/hooks/useAppParams'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { useSearchParams } from 'react-router-dom'; import ClusterContext from 'components/contexts/ClusterContext'; import { useTopics } from 'lib/hooks/api/topics'; diff --git a/frontend/src/components/Topics/List/__tests__/TopicTable.spec.tsx b/frontend/src/components/Topics/List/__tests__/TopicTable.spec.tsx index 61be3f136..cca768652 100644 --- a/frontend/src/components/Topics/List/__tests__/TopicTable.spec.tsx +++ b/frontend/src/components/Topics/List/__tests__/TopicTable.spec.tsx @@ -16,11 +16,6 @@ import { clusterTopicsPath } from 'lib/paths'; const clusterName = 'test-cluster'; -jest.mock('lib/hooks/redux', () => ({ - ...jest.requireActual('lib/hooks/redux'), - useAppDispatch: jest.fn(), -})); - const getButtonByName = (name: string) => screen.getByRole('button', { name }); jest.mock('lib/hooks/api/topics', () => ({ diff --git a/frontend/src/components/Topics/New/New.tsx b/frontend/src/components/Topics/New/New.tsx index c7528fb99..acc63185f 100644 --- a/frontend/src/components/Topics/New/New.tsx +++ b/frontend/src/components/Topics/New/New.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { TopicFormData } from 'redux/interfaces'; import { FormProvider, useForm } from 'react-hook-form'; import { ClusterNameRoute, clusterTopicsPath } from 'lib/paths'; import TopicForm from 'components/Topics/shared/Form/TopicForm'; @@ -9,6 +8,7 @@ import { topicFormValidationSchema } from 'lib/yupExtended'; import PageHeading from 'components/common/PageHeading/PageHeading'; import useAppParams from 'lib/hooks/useAppParams'; import { useCreateTopic } from 'lib/hooks/api/topics'; +import { TopicFormData } from 'lib/interfaces/topic'; enum Filters { NAME = 'name', diff --git a/frontend/src/components/Topics/Topic/Edit/Edit.tsx b/frontend/src/components/Topics/Topic/Edit/Edit.tsx index b8a576649..598ac5982 100644 --- a/frontend/src/components/Topics/Topic/Edit/Edit.tsx +++ b/frontend/src/components/Topics/Topic/Edit/Edit.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { TopicConfigByName, TopicFormData } from 'redux/interfaces'; import { useForm, FormProvider } from 'react-hook-form'; import TopicForm from 'components/Topics/shared/Form/TopicForm'; import { RouteParamsClusterTopic } from 'lib/paths'; @@ -16,6 +15,7 @@ import { } from 'lib/hooks/api/topics'; import DangerZone from 'components/Topics/Topic/Edit/DangerZone/DangerZone'; import { ConfigSource } from 'generated-sources'; +import { TopicConfigByName, TopicFormData } from 'lib/interfaces/topic'; export const TOPIC_EDIT_FORM_DEFAULT_PROPS = { partitions: 1, diff --git a/frontend/src/components/Topics/Topic/__test__/Topic.spec.tsx b/frontend/src/components/Topics/Topic/__test__/Topic.spec.tsx index 4ec45c3a5..7b5731767 100644 --- a/frontend/src/components/Topics/Topic/__test__/Topic.spec.tsx +++ b/frontend/src/components/Topics/Topic/__test__/Topic.spec.tsx @@ -22,7 +22,6 @@ import { useRecreateTopic, useTopicDetails, } from 'lib/hooks/api/topics'; -import { useAppDispatch } from 'lib/hooks/redux'; const mockNavigate = jest.fn(); jest.mock('react-router-dom', () => ({ @@ -36,14 +35,8 @@ jest.mock('lib/hooks/api/topics', () => ({ useClearTopicMessages: jest.fn(), })); -const unwrapMock = jest.fn(); const clearTopicMessages = jest.fn(); -jest.mock('lib/hooks/redux', () => ({ - ...jest.requireActual('lib/hooks/redux'), - useAppDispatch: jest.fn(), -})); - jest.mock('components/Topics/Topic/Overview/Overview', () => () => ( <>OverviewMock )); @@ -105,9 +98,6 @@ describe('Details', () => { (useClearTopicMessages as jest.Mock).mockImplementation(() => ({ mutateAsync: clearTopicMessages, })); - (useAppDispatch as jest.Mock).mockImplementation(() => () => ({ - unwrap: unwrapMock, - })); }); describe('Action Bar', () => { describe('when it has readonly flag', () => { diff --git a/frontend/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx b/frontend/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx index 95d3bcb15..75baca10e 100644 --- a/frontend/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx +++ b/frontend/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx @@ -2,7 +2,6 @@ import React, { useRef } from 'react'; import { ErrorMessage } from '@hookform/error-message'; import { TOPIC_CUSTOM_PARAMS } from 'lib/constants'; import { FieldArrayWithId, useFormContext, Controller } from 'react-hook-form'; -import { TopicConfigParams, TopicFormData } from 'redux/interfaces'; import { InputLabel } from 'components/common/Input/InputLabel.styled'; import { FormError } from 'components/common/Input/Input.styled'; import Select from 'components/common/Select/Select'; @@ -11,6 +10,7 @@ import IconButtonWrapper from 'components/common/Icons/IconButtonWrapper'; import CloseCircleIcon from 'components/common/Icons/CloseCircleIcon'; import * as C from 'components/Topics/shared/Form/TopicForm.styled'; import { ConfigSource } from 'generated-sources'; +import { TopicConfigParams, TopicFormData } from 'lib/interfaces/topic'; import * as S from './CustomParams.styled'; diff --git a/frontend/src/components/Topics/shared/Form/CustomParams/CustomParams.tsx b/frontend/src/components/Topics/shared/Form/CustomParams/CustomParams.tsx index bd000b00f..7895bffbf 100644 --- a/frontend/src/components/Topics/shared/Form/CustomParams/CustomParams.tsx +++ b/frontend/src/components/Topics/shared/Form/CustomParams/CustomParams.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import { TopicConfigParams, TopicFormData } from 'redux/interfaces'; import { useFieldArray, useFormContext, useWatch } from 'react-hook-form'; import { Button } from 'components/common/Button/Button'; import { TOPIC_CUSTOM_PARAMS_PREFIX } from 'lib/constants'; import PlusIcon from 'components/common/Icons/PlusIcon'; +import { TopicConfigParams, TopicFormData } from 'lib/interfaces/topic'; import CustomParamField from './CustomParamField'; import * as S from './CustomParams.styled'; diff --git a/frontend/src/components/Topics/shared/Form/TopicForm.tsx b/frontend/src/components/Topics/shared/Form/TopicForm.tsx index 14ca69ed2..47a9ac187 100644 --- a/frontend/src/components/Topics/shared/Form/TopicForm.tsx +++ b/frontend/src/components/Topics/shared/Form/TopicForm.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { useFormContext, Controller } from 'react-hook-form'; import { NOT_SET, BYTES_IN_GB } from 'lib/constants'; -import { ClusterName, TopicConfigParams, TopicName } from 'redux/interfaces'; import { ErrorMessage } from '@hookform/error-message'; import Select from 'components/common/Select/Select'; import Input from 'components/common/Input/Input'; @@ -12,6 +11,8 @@ import { StyledForm } from 'components/common/Form/Form.styled'; import { clusterTopicPath } from 'lib/paths'; import { useNavigate } from 'react-router-dom'; import useAppParams from 'lib/hooks/useAppParams'; +import { TopicConfigParams, TopicName } from 'lib/interfaces/topic'; +import { ClusterName } from 'lib/interfaces/cluster'; import CustomParams from './CustomParams/CustomParams'; import TimeToRetain from './TimeToRetain'; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 5ca52f75b..3d3672d2a 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,10 +1,8 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; -import { Provider } from 'react-redux'; import { ThemeModeProvider } from 'components/contexts/ThemeModeContext'; import App from 'components/App'; -import { store } from 'redux/store'; import 'lib/constants'; import 'theme/index.scss'; @@ -13,11 +11,9 @@ const container = const root = createRoot(container); root.render( - - - - - - - + + + + + ); diff --git a/frontend/src/lib/functions/nanoid.ts b/frontend/src/lib/functions/nanoid.ts new file mode 100644 index 000000000..14b2e49de --- /dev/null +++ b/frontend/src/lib/functions/nanoid.ts @@ -0,0 +1,22 @@ +// Borrowed from https://github.com/ai/nanoid/blob/3.0.2/non-secure/index.js +// This alphabet uses `A-Za-z0-9_-` symbols. A genetic algorithm helped +// optimize the gzip compression for this alphabet. +const urlAlphabet = + 'ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW'; + +/** + * + * @public + */ +export function nanoid(size = 21) { + let id = ''; + // A compact alternative for `for (var i = 0; i < step; i++)`. + let i = size; + // eslint-disable-next-line no-plusplus + while (i--) { + // `| 0` is more compact and faster than `Math.floor()`. + // eslint-disable-next-line no-bitwise + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id; +} diff --git a/frontend/src/lib/hooks/api/__tests__/schema.spec.ts b/frontend/src/lib/hooks/api/__tests__/schema.spec.ts new file mode 100644 index 000000000..eea7c94b8 --- /dev/null +++ b/frontend/src/lib/hooks/api/__tests__/schema.spec.ts @@ -0,0 +1,148 @@ +import { + expectQueryWorks, + renderQueryHook, + TestQueryClientProvider, +} from 'lib/testHelpers'; +import fetchMock from 'fetch-mock'; +import * as hooks from 'lib/hooks/api/schemas'; +import { act } from 'react-dom/test-utils'; +import { renderHook, waitFor } from '@testing-library/react'; +import { CompatibilityLevelCompatibilityEnum } from 'generated-sources'; +import { schemaVersion } from 'components/Schemas/Edit/__tests__/fixtures'; +import { + jsonSchema, + versionPayload, +} from 'components/Schemas/Details/__test__/fixtures'; +import { schemasPayload } from 'components/Schemas/List/__test__/fixtures'; + +const clusterName = 'test-cluster'; +const { subject } = schemaVersion; + +const schemasAPIUrl = `/api/clusters/${clusterName}/schemas`; +const schemasWithSubjectAPIUrl = `${schemasAPIUrl}/${subject}`; +const schemasAPILatestUrl = `${schemasWithSubjectAPIUrl}/latest`; +const schemasAPIVersionsUrl = `${schemasWithSubjectAPIUrl}/versions`; +const schemaCompatibilityUrl = `${schemasAPIUrl}/compatibility`; +const schemaCompatibilityWithSubjectUrl = `${schemasWithSubjectAPIUrl}/compatibility`; + +describe('Schema hooks', () => { + beforeEach(() => fetchMock.restore()); + + describe('Get Queries', () => { + describe('useGetSchemas', () => { + it('returns the correct data', async () => { + const mock = fetchMock.getOnce(schemasAPIUrl, schemasPayload); + const { result } = renderQueryHook(() => + hooks.useGetSchemas({ clusterName }) + ); + await expectQueryWorks(mock, result); + }); + }); + + describe('useGetLatestSchema', () => { + it('returns the correct data', async () => { + const mock = fetchMock.getOnce(schemasAPILatestUrl, schemaVersion); + const { result } = renderQueryHook(() => + hooks.useGetLatestSchema({ clusterName, subject }) + ); + await expectQueryWorks(mock, result); + }); + }); + + describe('useGetSchemasVersions', () => { + it('returns the correct data', async () => { + const mock = fetchMock.getOnce(schemasAPIVersionsUrl, versionPayload); + const { result } = renderQueryHook(() => + hooks.useGetSchemasVersions({ clusterName, subject }) + ); + await expectQueryWorks(mock, result); + }); + }); + + describe('useGetGlobalCompatibilityLayer', () => { + it('returns the correct data', async () => { + const mock = fetchMock.getOnce(schemaCompatibilityUrl, { + compatibility: CompatibilityLevelCompatibilityEnum.FULL, + }); + const { result } = renderQueryHook(() => + hooks.useGetGlobalCompatibilityLayer(clusterName) + ); + await expectQueryWorks(mock, result); + }); + }); + }); + + describe('Mutations', () => { + describe('useCreateSchema', () => { + it('returns the correct data', async () => { + const mock = fetchMock.postOnce(schemasAPIUrl, jsonSchema); + const { result } = renderHook( + () => hooks.useCreateSchema(clusterName), + { wrapper: TestQueryClientProvider } + ); + await act(async () => { + await result.current.mutateAsync(jsonSchema); + }); + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()); + expect(mock.calls()).toHaveLength(1); + }); + }); + + describe('useUpdateSchemaCompatibilityLayer', () => { + it('returns the correct data', async () => { + const mock = fetchMock.putOnce(schemaCompatibilityWithSubjectUrl, 200); + const { result } = renderHook( + () => + hooks.useUpdateSchemaCompatibilityLayer({ clusterName, subject }), + { wrapper: TestQueryClientProvider } + ); + await act(async () => { + await result.current.mutateAsync({ + compatibilityLevel: { + compatibility: CompatibilityLevelCompatibilityEnum.BACKWARD, + }, + }); + }); + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()); + expect(mock.calls()).toHaveLength(1); + }); + }); + + describe('useUpdateGlobalSchemaCompatibilityLevel', () => { + it('returns the correct data', async () => { + const mock = fetchMock.putOnce(schemaCompatibilityUrl, { + body: { + compatibility: CompatibilityLevelCompatibilityEnum.BACKWARD, + }, + }); + const { result } = renderHook( + () => hooks.useUpdateGlobalSchemaCompatibilityLevel(clusterName), + { wrapper: TestQueryClientProvider } + ); + + await act(() => + result.current.mutateAsync({ + compatibilityLevel: { + compatibility: CompatibilityLevelCompatibilityEnum.BACKWARD, + }, + }) + ); + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()); + expect(mock.calls()).toHaveLength(1); + }); + }); + + describe('useDeleteSchema', () => { + it('returns the correct data', async () => { + const mock = fetchMock.deleteOnce(schemasWithSubjectAPIUrl, 200); + const { result } = renderHook( + () => hooks.useDeleteSchema({ clusterName, subject }), + { wrapper: TestQueryClientProvider } + ); + await act(() => result.current.mutateAsync()); + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()); + expect(mock.calls()).toHaveLength(1); + }); + }); + }); +}); diff --git a/frontend/src/lib/hooks/api/__tests__/topics.spec.ts b/frontend/src/lib/hooks/api/__tests__/topics.spec.ts index 802368495..6007f3356 100644 --- a/frontend/src/lib/hooks/api/__tests__/topics.spec.ts +++ b/frontend/src/lib/hooks/api/__tests__/topics.spec.ts @@ -7,8 +7,8 @@ import { import * as hooks from 'lib/hooks/api/topics'; import fetchMock from 'fetch-mock'; import { externalTopicPayload, topicConfigPayload } from 'lib/fixtures/topics'; -import { TopicFormData, TopicFormDataRaw } from 'redux/interfaces'; import { CreateTopicMessage } from 'generated-sources'; +import { TopicFormData, TopicFormDataRaw } from 'lib/interfaces/topic'; const clusterName = 'test-cluster'; const topicName = 'test-topic'; diff --git a/frontend/src/lib/hooks/api/acl.ts b/frontend/src/lib/hooks/api/acl.ts index 498b34191..318768781 100644 --- a/frontend/src/lib/hooks/api/acl.ts +++ b/frontend/src/lib/hooks/api/acl.ts @@ -5,7 +5,7 @@ import { useQuery, useQueryClient, } from '@tanstack/react-query'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { showSuccessAlert } from 'lib/errorHandling'; import { CreateConsumerAcl, diff --git a/frontend/src/lib/hooks/api/brokers.ts b/frontend/src/lib/hooks/api/brokers.ts index 073e2eb75..064bb0d66 100644 --- a/frontend/src/lib/hooks/api/brokers.ts +++ b/frontend/src/lib/hooks/api/brokers.ts @@ -1,6 +1,6 @@ import { brokersApiClient as api } from 'lib/api'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { BrokerConfigItem } from 'generated-sources'; interface UpdateBrokerConfigProps { diff --git a/frontend/src/lib/hooks/api/clusters.ts b/frontend/src/lib/hooks/api/clusters.ts index 443363d3f..1d3f2c05d 100644 --- a/frontend/src/lib/hooks/api/clusters.ts +++ b/frontend/src/lib/hooks/api/clusters.ts @@ -1,6 +1,6 @@ import { clustersApiClient as api } from 'lib/api'; import { useQuery } from '@tanstack/react-query'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; export function useClusters() { return useQuery(['clusters'], () => api.getClusters(), { suspense: false }); diff --git a/frontend/src/lib/hooks/api/consumers.ts b/frontend/src/lib/hooks/api/consumers.ts index c0089e1f0..85ae048a9 100644 --- a/frontend/src/lib/hooks/api/consumers.ts +++ b/frontend/src/lib/hooks/api/consumers.ts @@ -1,6 +1,6 @@ import { consumerGroupsApiClient as api } from 'lib/api'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { ConsumerGroup, ConsumerGroupOffsetsReset, diff --git a/frontend/src/lib/hooks/api/kafkaConnect.ts b/frontend/src/lib/hooks/api/kafkaConnect.ts index 1d01d4919..c17b381e4 100644 --- a/frontend/src/lib/hooks/api/kafkaConnect.ts +++ b/frontend/src/lib/hooks/api/kafkaConnect.ts @@ -7,7 +7,7 @@ import { import { kafkaConnectApiClient as api } from 'lib/api'; import sortBy from 'lodash/sortBy'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { showSuccessAlert } from 'lib/errorHandling'; interface UseConnectorProps { diff --git a/frontend/src/lib/hooks/api/ksqlDb.tsx b/frontend/src/lib/hooks/api/ksqlDb.tsx index 366141e82..e562e7c2f 100644 --- a/frontend/src/lib/hooks/api/ksqlDb.tsx +++ b/frontend/src/lib/hooks/api/ksqlDb.tsx @@ -1,6 +1,6 @@ import { ksqlDbApiClient as api } from 'lib/api'; import { useMutation, useQueries } from '@tanstack/react-query'; -import { ClusterName } from 'redux/interfaces'; +import { ClusterName } from 'lib/interfaces/cluster'; import { BASE_PARAMS } from 'lib/constants'; import React from 'react'; import { fetchEventSource } from '@microsoft/fetch-event-source'; diff --git a/frontend/src/lib/hooks/api/schemas.ts b/frontend/src/lib/hooks/api/schemas.ts new file mode 100644 index 000000000..7082d180a --- /dev/null +++ b/frontend/src/lib/hooks/api/schemas.ts @@ -0,0 +1,177 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { + GLOBAL_COMPATIBILITY_SCHEMAS_QUERY_KEY, + LATEST_SCHEMA_QUERY_KEY, + SCHEMA_QUERY_KEY, + SCHEMAS_VERSION_QUERY_KEY, +} from 'lib/queries'; +import { + CompatibilityLevel, + GetAllVersionsBySubjectRequest, + GetLatestSchemaRequest, + GetSchemasRequest, + NewSchemaSubject, + SchemaSubject, + SchemaSubjectsResponse, + UpdateGlobalSchemaCompatibilityLevelRequest, + UpdateSchemaCompatibilityLevelRequest, +} from 'generated-sources'; +import { schemasApiClient } from 'lib/api'; +import { ClusterName } from 'lib/interfaces/cluster'; + +export function useGetLatestSchema(param: GetLatestSchemaRequest) { + return useQuery({ + queryKey: [ + SCHEMA_QUERY_KEY, + LATEST_SCHEMA_QUERY_KEY, + param.clusterName, + param.subject, + ], + queryFn: () => schemasApiClient.getLatestSchema(param), + }); +} + +export function useGetSchemas({ + clusterName, + page, + perPage, + search, +}: GetSchemasRequest) { + return useQuery({ + queryKey: [SCHEMA_QUERY_KEY, clusterName, page, perPage, search], + queryFn: () => + schemasApiClient.getSchemas({ + clusterName, + page, + perPage, + search: search || undefined, + }), + }); +} + +export function useGetSchemasVersions({ + clusterName, + subject, +}: GetAllVersionsBySubjectRequest) { + return useQuery>({ + queryKey: [SCHEMAS_VERSION_QUERY_KEY, clusterName, subject], + queryFn: () => + schemasApiClient.getAllVersionsBySubject({ + clusterName, + subject, + }), + }); +} + +export function useGetGlobalCompatibilityLayer(clusterName: ClusterName) { + return useQuery({ + queryKey: [GLOBAL_COMPATIBILITY_SCHEMAS_QUERY_KEY, clusterName], + queryFn: () => + schemasApiClient.getGlobalSchemaCompatibilityLevel({ + clusterName, + }), + }); +} + +export function useCreateSchema(clusterName: ClusterName) { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: ({ subject, schema, schemaType }) => + schemasApiClient.createNewSchema({ + clusterName, + newSchemaSubject: { subject, schema, schemaType }, + }), + onSuccess: () => { + return queryClient.invalidateQueries({ + predicate: (query) => + query.queryKey[0] === SCHEMA_QUERY_KEY && + query.queryKey[1] === clusterName, + }); + }, + }); +} + +export function useUpdateSchemaCompatibilityLayer({ + clusterName, + subject, +}: { + clusterName: ClusterName; + subject: string; +}) { + const queryClient = useQueryClient(); + return useMutation< + void, + void, + Omit + >({ + mutationFn: ({ compatibilityLevel }) => + schemasApiClient.updateSchemaCompatibilityLevel({ + clusterName, + subject, + compatibilityLevel, + }), + onSuccess: () => { + return queryClient.invalidateQueries({ + predicate: (query) => + query.queryKey[0] === SCHEMA_QUERY_KEY && + query.queryKey[1] === clusterName, + }); + }, + }); +} + +export function useUpdateGlobalSchemaCompatibilityLevel( + clusterName: ClusterName +) { + const queryClient = useQueryClient(); + + return useMutation< + void, + void, + Omit + >({ + mutationFn: ({ compatibilityLevel }) => + schemasApiClient.updateGlobalSchemaCompatibilityLevel({ + clusterName, + compatibilityLevel, + }), + onSuccess: () => { + return Promise.all([ + queryClient.invalidateQueries([ + GLOBAL_COMPATIBILITY_SCHEMAS_QUERY_KEY, + clusterName, + ]), + queryClient.invalidateQueries({ + predicate: (query) => + query.queryKey[0] === SCHEMA_QUERY_KEY && + query.queryKey[1] === clusterName, + }), + ]); + }, + }); +} + +export function useDeleteSchema({ + clusterName, + subject, +}: { + clusterName: ClusterName; + subject: string; +}) { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: () => + schemasApiClient.deleteSchema({ + clusterName, + subject, + }), + onSuccess: () => { + return queryClient.invalidateQueries({ + predicate: (query) => + query.queryKey[0] === SCHEMA_QUERY_KEY && + query.queryKey[1] === clusterName, + }); + }, + }); +} diff --git a/frontend/src/lib/hooks/api/topicMessages.tsx b/frontend/src/lib/hooks/api/topicMessages.tsx index cf22148ac..e552c0dbf 100644 --- a/frontend/src/lib/hooks/api/topicMessages.tsx +++ b/frontend/src/lib/hooks/api/topicMessages.tsx @@ -1,7 +1,6 @@ import React, { useCallback, useRef } from 'react'; import { fetchEventSource } from '@microsoft/fetch-event-source'; import { BASE_PARAMS, MESSAGES_PER_PAGE } from 'lib/constants'; -import { ClusterName, TopicName } from 'redux/interfaces'; import { GetSerdesRequest, PollingMode, @@ -17,6 +16,8 @@ import { useSearchParams } from 'react-router-dom'; import { MessagesFilterKeys } from 'lib/hooks/useMessagesFilters'; import { convertStrToPollingMode } from 'lib/hooks/filterUtils'; import { useMessageFiltersStore } from 'lib/hooks/useMessageFiltersStore'; +import { TopicName } from 'lib/interfaces/topic'; +import { ClusterName } from 'lib/interfaces/cluster'; interface UseTopicMessagesProps { clusterName: ClusterName; diff --git a/frontend/src/lib/hooks/api/topics.ts b/frontend/src/lib/hooks/api/topics.ts index 3f68a1709..b0aac312d 100644 --- a/frontend/src/lib/hooks/api/topics.ts +++ b/frontend/src/lib/hooks/api/topics.ts @@ -5,12 +5,6 @@ import { messagesApiClient, } from 'lib/api'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { - ClusterName, - TopicFormData, - TopicFormDataRaw, - TopicFormFormattedParams, -} from 'redux/interfaces'; import { CreateTopicMessage, GetTopicDetailsRequest, @@ -21,6 +15,12 @@ import { TopicUpdate, } from 'generated-sources'; import { showServerError, showSuccessAlert } from 'lib/errorHandling'; +import { ClusterName } from 'lib/interfaces/cluster'; +import { + TopicFormData, + TopicFormDataRaw, + TopicFormFormattedParams, +} from 'lib/interfaces/topic'; export const topicKeys = { all: (clusterName: ClusterName) => diff --git a/frontend/src/lib/hooks/redux.ts b/frontend/src/lib/hooks/redux.ts deleted file mode 100644 index 40471e04a..000000000 --- a/frontend/src/lib/hooks/redux.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; -import { AppDispatch, RootState } from 'redux/interfaces'; - -export const useAppDispatch = () => useDispatch(); -export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/frontend/src/redux/interfaces/cluster.ts b/frontend/src/lib/interfaces/cluster.ts similarity index 100% rename from frontend/src/redux/interfaces/cluster.ts rename to frontend/src/lib/interfaces/cluster.ts diff --git a/frontend/src/redux/interfaces/schema.ts b/frontend/src/lib/interfaces/schema.ts similarity index 100% rename from frontend/src/redux/interfaces/schema.ts rename to frontend/src/lib/interfaces/schema.ts diff --git a/frontend/src/redux/interfaces/topic.ts b/frontend/src/lib/interfaces/topic.ts similarity index 76% rename from frontend/src/redux/interfaces/topic.ts rename to frontend/src/lib/interfaces/topic.ts index bdc25ee0c..126294a1f 100644 --- a/frontend/src/redux/interfaces/topic.ts +++ b/frontend/src/lib/interfaces/topic.ts @@ -1,10 +1,4 @@ -import { - Topic, - TopicConfig, - TopicCreation, - TopicMessage, - TopicMessageConsuming, -} from 'generated-sources'; +import { Topic, TopicConfig, TopicCreation } from 'generated-sources'; export type TopicName = Topic['name']; @@ -50,11 +44,3 @@ export interface TopicFormData { value: string; }[]; } - -export interface TopicMessagesState { - messages: TopicMessage[]; - phase?: string; - meta: TopicMessageConsuming; - messageEventType?: string; - isFetching: boolean; -} diff --git a/frontend/src/lib/paths.ts b/frontend/src/lib/paths.ts index 62b19568c..9f961b261 100644 --- a/frontend/src/lib/paths.ts +++ b/frontend/src/lib/paths.ts @@ -1,8 +1,10 @@ import { Broker, Connect, Connector } from 'generated-sources'; -import { ClusterName, SchemaName, TopicName } from 'redux/interfaces'; import { GIT_REPO_LINK } from './constants'; import { ConsumerGroupID } from './hooks/api/consumers'; +import { ClusterName } from './interfaces/cluster'; +import { SchemaName } from './interfaces/schema'; +import { TopicName } from './interfaces/topic'; export const gitCommitPath = (commit: string) => `${GIT_REPO_LINK}/commit/${commit}`; diff --git a/frontend/src/lib/queries.ts b/frontend/src/lib/queries.ts new file mode 100644 index 000000000..4bbf9e59a --- /dev/null +++ b/frontend/src/lib/queries.ts @@ -0,0 +1,8 @@ +// TODO all the other query key should be transferred here + +// SCHEMAS +export const SCHEMA_QUERY_KEY = 'schemas'; +export const LATEST_SCHEMA_QUERY_KEY = 'latest_schemas'; +export const SCHEMAS_VERSION_QUERY_KEY = 'schemas_version'; +export const GLOBAL_COMPATIBILITY_SCHEMAS_QUERY_KEY = + 'global_compatibility_schemas'; diff --git a/frontend/src/lib/testHelpers.tsx b/frontend/src/lib/testHelpers.tsx index 06fcfcad4..1a6732c06 100644 --- a/frontend/src/lib/testHelpers.tsx +++ b/frontend/src/lib/testHelpers.tsx @@ -6,7 +6,6 @@ import { Routes, } from 'react-router-dom'; import fetchMock from 'fetch-mock'; -import { Provider } from 'react-redux'; import { ThemeProvider } from 'styled-components'; import { theme } from 'theme/theme'; import { @@ -15,10 +14,6 @@ import { RenderOptions, waitFor, } from '@testing-library/react'; -import { AnyAction, Store } from 'redux'; -import { RootState } from 'redux/interfaces'; -import { configureStore } from '@reduxjs/toolkit'; -import rootReducer from 'redux/reducers'; import { QueryClient, QueryClientProvider, @@ -32,8 +27,6 @@ import { UserInfoRolesAccessContext } from 'components/contexts/UserInfoRolesAcc import { RolesType, modifyRolesData } from './permissions'; interface CustomRenderOptions extends Omit { - preloadedState?: Partial; - store?: Store, AnyAction>; initialEntries?: MemoryRouterProps['initialEntries']; userInfo?: { roles?: RolesType; @@ -107,11 +100,6 @@ const TestUserInfoProvider: React.FC< const customRender = ( ui: ReactElement, { - preloadedState, - store = configureStore({ - reducer: rootReducer, - preloadedState, - }), initialEntries, userInfo, globalSettings, @@ -129,14 +117,12 @@ const customRender = ( - - -
- {children} - -
-
-
+ +
+ {children} + +
+
diff --git a/frontend/src/redux/interfaces/consumerGroup.ts b/frontend/src/redux/interfaces/consumerGroup.ts deleted file mode 100644 index 45412e264..000000000 --- a/frontend/src/redux/interfaces/consumerGroup.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { - ConsumerGroup, - ConsumerGroupOffsetsResetType, -} from 'generated-sources'; - -import { ClusterName } from './cluster'; - -export interface ConsumerGroupResetOffsetRequestParams { - clusterName: ClusterName; - consumerGroupID: ConsumerGroup['groupId']; - requestBody: { - topic: string; - resetType: ConsumerGroupOffsetsResetType; - partitionsOffsets?: { offset: string; partition: number }[]; - resetToTimestamp?: Date; - partitions: number[]; - }; -} diff --git a/frontend/src/redux/interfaces/index.ts b/frontend/src/redux/interfaces/index.ts deleted file mode 100644 index 0c8ddf234..000000000 --- a/frontend/src/redux/interfaces/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import rootReducer from 'redux/reducers'; -import { store } from 'redux/store'; - -export * from './topic'; -export * from './cluster'; -export * from './consumerGroup'; -export * from './schema'; -export * from './loader'; - -export type RootState = ReturnType; -export type AppDispatch = typeof store.dispatch; diff --git a/frontend/src/redux/interfaces/loader.ts b/frontend/src/redux/interfaces/loader.ts deleted file mode 100644 index 67066399e..000000000 --- a/frontend/src/redux/interfaces/loader.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { AsyncRequestStatus } from 'lib/constants'; - -export interface LoaderSliceState { - [key: string]: AsyncRequestStatus; -} diff --git a/frontend/src/redux/reducers/index.ts b/frontend/src/redux/reducers/index.ts deleted file mode 100644 index 6385e0710..000000000 --- a/frontend/src/redux/reducers/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { combineReducers } from '@reduxjs/toolkit'; -import loader from 'redux/reducers/loader/loaderSlice'; -import schemas from 'redux/reducers/schemas/schemasSlice'; - -export default combineReducers({ - loader, - schemas, -}); diff --git a/frontend/src/redux/reducers/loader/loaderSlice.ts b/frontend/src/redux/reducers/loader/loaderSlice.ts deleted file mode 100644 index 294b35911..000000000 --- a/frontend/src/redux/reducers/loader/loaderSlice.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { - UnknownAsyncThunkFulfilledAction, - UnknownAsyncThunkPendingAction, - UnknownAsyncThunkRejectedAction, -} from '@reduxjs/toolkit/dist/matchers'; -import { AsyncRequestStatus } from 'lib/constants'; -import { LoaderSliceState } from 'redux/interfaces'; - -const initialState: LoaderSliceState = {}; - -const loaderSlice = createSlice({ - name: 'loader', - initialState, - reducers: { - resetLoaderById: ( - state: LoaderSliceState, - { payload }: PayloadAction - ) => { - delete state[payload]; - }, - }, - extraReducers: (builder) => { - builder - .addMatcher( - (action): action is UnknownAsyncThunkPendingAction => - action.type.endsWith('/pending'), - (state, { type }) => { - state[type.replace('/pending', '')] = AsyncRequestStatus.pending; - } - ) - .addMatcher( - (action): action is UnknownAsyncThunkFulfilledAction => - action.type.endsWith('/fulfilled'), - (state, { type }) => { - state[type.replace('/fulfilled', '')] = AsyncRequestStatus.fulfilled; - } - ) - .addMatcher( - (action): action is UnknownAsyncThunkRejectedAction => - action.type.endsWith('/rejected'), - (state, { type }) => { - state[type.replace('/rejected', '')] = AsyncRequestStatus.rejected; - } - ); - }, -}); - -export const { resetLoaderById } = loaderSlice.actions; - -export default loaderSlice.reducer; diff --git a/frontend/src/redux/reducers/loader/selectors.ts b/frontend/src/redux/reducers/loader/selectors.ts deleted file mode 100644 index 2decd3446..000000000 --- a/frontend/src/redux/reducers/loader/selectors.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { RootState } from 'redux/interfaces'; -import { AsyncRequestStatus } from 'lib/constants'; - -export const createFetchingSelector = (action: string) => (state: RootState) => - state.loader[action] || AsyncRequestStatus.initial; diff --git a/frontend/src/redux/reducers/schemas/schemasSlice.ts b/frontend/src/redux/reducers/schemas/schemasSlice.ts deleted file mode 100644 index 018775ced..000000000 --- a/frontend/src/redux/reducers/schemas/schemasSlice.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { - createAsyncThunk, - createEntityAdapter, - createSelector, - createSlice, -} from '@reduxjs/toolkit'; -import { - SchemaSubject, - SchemaSubjectsResponse, - GetSchemasRequest, - GetLatestSchemaRequest, -} from 'generated-sources'; -import { schemasApiClient } from 'lib/api'; -import { AsyncRequestStatus } from 'lib/constants'; -import { getResponse, showServerError } from 'lib/errorHandling'; -import { ClusterName, RootState } from 'redux/interfaces'; -import { createFetchingSelector } from 'redux/reducers/loader/selectors'; - -export const SCHEMA_LATEST_FETCH_ACTION = 'schemas/latest/fetch'; -export const fetchLatestSchema = createAsyncThunk< - SchemaSubject, - GetLatestSchemaRequest ->(SCHEMA_LATEST_FETCH_ACTION, async (schemaParams, { rejectWithValue }) => { - try { - return await schemasApiClient.getLatestSchema(schemaParams); - } catch (error) { - showServerError(error as Response); - return rejectWithValue(await getResponse(error as Response)); - } -}); - -export const SCHEMAS_FETCH_ACTION = 'schemas/fetch'; -export const fetchSchemas = createAsyncThunk< - SchemaSubjectsResponse, - GetSchemasRequest ->( - SCHEMAS_FETCH_ACTION, - async ({ clusterName, page, perPage, search }, { rejectWithValue }) => { - try { - return await schemasApiClient.getSchemas({ - clusterName, - page, - perPage, - search: search || undefined, - }); - } catch (error) { - showServerError(error as Response); - return rejectWithValue(await getResponse(error as Response)); - } - } -); - -export const SCHEMAS_VERSIONS_FETCH_ACTION = 'schemas/versions/fetch'; -export const fetchSchemaVersions = createAsyncThunk< - SchemaSubject[], - { clusterName: ClusterName; subject: SchemaSubject['subject'] } ->( - SCHEMAS_VERSIONS_FETCH_ACTION, - async ({ clusterName, subject }, { rejectWithValue }) => { - try { - return await schemasApiClient.getAllVersionsBySubject({ - clusterName, - subject, - }); - } catch (error) { - showServerError(error as Response); - return rejectWithValue(await getResponse(error as Response)); - } - } -); - -const schemaVersionsAdapter = createEntityAdapter({ - selectId: ({ id }) => id, - sortComparer: (a, b) => b.id - a.id, -}); -const schemasAdapter = createEntityAdapter({ - selectId: ({ subject }) => subject, -}); - -const SCHEMAS_PAGE_COUNT = 1; - -const initialState = { - totalPages: SCHEMAS_PAGE_COUNT, - ...schemasAdapter.getInitialState(), - versions: { - ...schemaVersionsAdapter.getInitialState(), - latest: null, - }, -}; - -const schemasSlice = createSlice({ - name: 'schemas', - initialState, - reducers: { - schemaAdded: schemasAdapter.addOne, - schemaUpdated: schemasAdapter.upsertOne, - }, - extraReducers: (builder) => { - builder.addCase(fetchSchemas.fulfilled, (state, { payload }) => { - state.totalPages = payload.pageCount || SCHEMAS_PAGE_COUNT; - schemasAdapter.setAll(state, payload.schemas || []); - }); - builder.addCase(fetchLatestSchema.fulfilled, (state, { payload }) => { - state.versions.latest = payload; - }); - builder.addCase(fetchSchemaVersions.fulfilled, (state, { payload }) => { - schemaVersionsAdapter.setAll(state.versions, payload); - }); - }, -}); - -export const { selectAll: selectAllSchemas } = - schemasAdapter.getSelectors((state) => state.schemas); - -export const { selectAll: selectAllSchemaVersions } = - schemaVersionsAdapter.getSelectors( - (state) => state.schemas.versions - ); - -const getSchemaVersions = (state: RootState) => state.schemas.versions; -export const getSchemaLatest = createSelector( - getSchemaVersions, - (state) => state.latest -); - -export const { schemaAdded, schemaUpdated } = schemasSlice.actions; - -export const getAreSchemasFulfilled = createSelector( - createFetchingSelector(SCHEMAS_FETCH_ACTION), - (status) => status === AsyncRequestStatus.fulfilled -); - -export const getAreSchemaLatestFulfilled = createSelector( - createFetchingSelector(SCHEMA_LATEST_FETCH_ACTION), - (status) => status === AsyncRequestStatus.fulfilled -); -export const getAreSchemaLatestRejected = createSelector( - createFetchingSelector(SCHEMA_LATEST_FETCH_ACTION), - (status) => status === AsyncRequestStatus.rejected -); - -export const getAreSchemaVersionsFulfilled = createSelector( - createFetchingSelector(SCHEMAS_VERSIONS_FETCH_ACTION), - (status) => status === AsyncRequestStatus.fulfilled -); - -export default schemasSlice.reducer; diff --git a/frontend/src/redux/store/index.ts b/frontend/src/redux/store/index.ts deleted file mode 100644 index 7d37a77f4..000000000 --- a/frontend/src/redux/store/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { configureStore } from '@reduxjs/toolkit'; -import { RootState } from 'redux/interfaces'; -import rootReducer from 'redux/reducers'; - -export const store = configureStore({ - reducer: rootReducer, -});