diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml
index a693006d..89eff784 100644
--- a/.github/workflows/dev.yml
+++ b/.github/workflows/dev.yml
@@ -29,7 +29,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: '3.12'
- cache: 'pip'
- run: pip install -r requirements.txt
@@ -59,7 +58,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: '3.12'
- cache: 'pip'
- name: Setup API environment
run: make backend/setup
@@ -92,7 +90,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: '3.12'
- cache: 'pip'
- name: Setup Python Environment
run: |
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c395b870..64ba3c95 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -28,7 +28,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: '3.12'
- cache: 'pip'
- run: pip install -r requirements.txt
@@ -58,7 +57,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: '3.12'
- cache: 'pip'
- name: Setup API environment
run: make backend/setup
diff --git a/.github/workflows/release_sdk.yml b/.github/workflows/release_sdk.yml
index b709130b..239e21f1 100644
--- a/.github/workflows/release_sdk.yml
+++ b/.github/workflows/release_sdk.yml
@@ -33,7 +33,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: '3.12'
- cache: 'pip'
- name: Setup Python Environment
run: |
diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml
index 17568db4..7e46fa26 100644
--- a/.github/workflows/ui-tests.yml
+++ b/.github/workflows/ui-tests.yml
@@ -41,3 +41,13 @@ jobs:
E2E_DOMAIN_NAME: ${{ secrets.E2E_DOMAIN_NAME }}
E2E_RESOURCE_PREFIX: ${{ secrets.E2E_RESOURCE_PREFIX }}
AWS_REGION: ${{ secrets.AWS_REGION }}
+
+ - name: Upload Playwright results
+ if: failure()
+ uses: actions/upload-artifact@v4
+ with:
+ name: playwright-results
+ path: |
+ frontend/test-results/
+ frontend/playwright-report/
+ retention-days: 7
diff --git a/Makefile b/Makefile
index 0586427c..0439ec19 100644
--- a/Makefile
+++ b/Makefile
@@ -191,7 +191,7 @@ infra/backend: ## Create terraform backend for infrastructure
@cd infrastructure/; ./scripts/infra_make_helper.sh create_backend
infra/init: ## Terraform init: make infra/init block=
- @cd infrastructure/; ./scripts/infra_make_helper.sh run_init "${block}"
+ @cd infrastructure/; ./scripts/infra_make_helper.sh run_init "${block}" "${args}"
infra/plan: ## Terraform view infrastructure changes: make infra/plan block=
@cd infrastructure/; ./scripts/infra_make_helper.sh run_tf plan "${block}" "${env}"
diff --git a/backend/api/application/services/authorisation/authorisation_service.py b/backend/api/application/services/authorisation/authorisation_service.py
index 7957cd6f..934a11ad 100644
--- a/backend/api/application/services/authorisation/authorisation_service.py
+++ b/backend/api/application/services/authorisation/authorisation_service.py
@@ -164,6 +164,17 @@ def get_subject_id(request: Request):
return parsed_token.subject if token else None
+def get_username(request: Request) -> Optional[str]:
+ token = get_token(request)
+ if not token:
+ return None
+ try:
+ parsed_token = parse_token(token)
+ except DecodeError:
+ return None
+ return parsed_token.username
+
+
def check_credentials_availability(
browser_request: bool,
client_token: Optional[str],
diff --git a/backend/api/application/services/data_service.py b/backend/api/application/services/data_service.py
index 5963f760..fcc98a7c 100644
--- a/backend/api/application/services/data_service.py
+++ b/backend/api/application/services/data_service.py
@@ -1,4 +1,5 @@
import uuid
+from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from threading import Thread
from typing import List, Tuple
@@ -191,6 +192,22 @@ def get_last_updated_time(self, metadata: DatasetMetadata) -> str:
)
return last_updated or "Never updated"
+ def enrich_datasets_for_ui(self, datasets: List[DatasetMetadata]) -> List[dict]:
+ def enrich(dataset: DatasetMetadata) -> dict:
+ d = dataset.to_dict()
+ try:
+ d["last_updated"] = self.get_last_updated_time(dataset)
+ except Exception:
+ d["last_updated"] = None
+ try:
+ d["last_uploaded_by"] = self.get_last_uploader(dataset)
+ except Exception:
+ d["last_uploaded_by"] = None
+ return d
+
+ with ThreadPoolExecutor(max_workers=10) as pool:
+ return list(pool.map(enrich, datasets))
+
def get_last_uploader(self, metadata: DatasetMetadata) -> str:
"""
Get the name of the user who last successfully uploaded to this dataset.
diff --git a/backend/api/controller/datasets.py b/backend/api/controller/datasets.py
index 6bc955e8..875b8db5 100644
--- a/backend/api/controller/datasets.py
+++ b/backend/api/controller/datasets.py
@@ -18,13 +18,13 @@
DatasetAccessEvaluator,
)
from api.application.services.data_service import DataService
-
+from api.application.services.job_service import JobService
from api.application.services.delete_service import DeleteService
from api.application.services.format_service import FormatService
from api.application.services.schema_service import SchemaService
from api.application.services.search_service import SearchService
from api.common.data_handlers import store_file_to_disk
-from api.common.utilities import strtobool
+from api.common.utilities import build_error_message_list, construct_dataset_metadata, strtobool
from api.common.config.auth import Action
from api.common.config.constants import (
BASE_API_PATH,
@@ -40,7 +40,6 @@
InvalidFileUploadError,
)
from api.common.logger import AppLogger
-from api.common.utilities import construct_dataset_metadata
from api.domain.dataset_filters import DatasetFilters
from api.domain.dataset_metadata import DatasetMetadata
from api.domain.schema_metadata import SchemaMetadata
@@ -53,6 +52,7 @@
athena_adapter = AthenaAdapter()
data_service = DataService()
+job_service = JobService()
delete_service = DeleteService()
schema_service = SchemaService()
data_access_evaluator = DatasetAccessEvaluator()
@@ -567,9 +567,15 @@ async def query_dataset(
### Click `Try it out` to use the endpoint
"""
- df = data_service.query_data(
- construct_dataset_metadata(layer, domain, dataset, version), query
- )
+ subject_id = get_subject_id(request)
+ dataset_metadata = construct_dataset_metadata(layer, domain, dataset, version)
+ query_job = job_service.create_query_job(subject_id, dataset_metadata)
+ try:
+ df = data_service.query_data(dataset_metadata, query)
+ except Exception as error:
+ job_service.fail(query_job, build_error_message_list(error))
+ raise
+ job_service.succeed_query(query_job, url=None)
if df.shape[0] == 0:
# Return 204 if dataframe is empty
return PlainTextResponse(
diff --git a/backend/api/domain/schema_metadata.py b/backend/api/domain/schema_metadata.py
index 0688df2a..322a1a31 100644
--- a/backend/api/domain/schema_metadata.py
+++ b/backend/api/domain/schema_metadata.py
@@ -40,11 +40,7 @@ def get_is_latest_version(self) -> bool:
return self.is_latest_version
def remove_duplicates(self):
- updated_key_only_list = []
-
- if len(self.key_only_tags) != 0 and self.key_value_tags:
- for key in self.key_only_tags:
- if key not in self.key_value_tags.keys():
- updated_key_only_list.append(key)
-
- self.key_only_tags = updated_key_only_list
+ if self.key_value_tags:
+ self.key_only_tags = [
+ key for key in self.key_only_tags if key not in self.key_value_tags
+ ]
diff --git a/backend/api/domain/token.py b/backend/api/domain/token.py
index 586929b3..662532fb 100644
--- a/backend/api/domain/token.py
+++ b/backend/api/domain/token.py
@@ -4,6 +4,7 @@
class Token:
def __init__(self, payload: dict):
self.subject: str = self._extract_subject(payload)
+ self.username: str | None = payload.get("cognito:username") or payload.get("username")
def _extract_subject(self, payload: dict) -> str:
try:
diff --git a/backend/api/entry.py b/backend/api/entry.py
index 0d01e0a4..f3b71f1f 100644
--- a/backend/api/entry.py
+++ b/backend/api/entry.py
@@ -11,11 +11,13 @@
from api.application.services.authorisation.authorisation_service import (
secure_endpoint,
get_subject_id,
+ get_username,
)
from api.application.services.permissions_service import PermissionsService
from api.application.services.authorisation.dataset_access_evaluator import (
DatasetAccessEvaluator,
)
+from api.application.services.data_service import DataService
from api.common.config.auth import IDENTITY_PROVIDER_BASE_URL, Action
from api.common.config.docs import (
custom_openapi_docs_generator,
@@ -57,6 +59,7 @@
permissions_service = PermissionsService()
upload_service = DatasetAccessEvaluator()
+data_service = DataService()
app = FastAPI(
openapi_url=f"{BASE_API_PATH}/openapi.json", docs_url=None
@@ -172,7 +175,7 @@ async def methods(request: Request):
except AWSServiceError as error:
error_message = error.message
- return {"error_message": error_message, **allowed_actions}
+ return {"error_message": error_message, "username": get_username(request), **allowed_actions}
@app.get(
@@ -194,7 +197,7 @@ async def get_permissions_ui():
async def get_datasets_ui(action: Action, request: Request):
subject_id = get_subject_id(request)
datasets = upload_service.get_authorised_datasets(subject_id, action)
- return [dataset.to_dict() for dataset in datasets]
+ return data_service.enrich_datasets_for_ui(datasets)
@app.get("/favicon.ico", include_in_schema=False)
diff --git a/backend/test/api/controller/test_datasets.py b/backend/test/api/controller/test_datasets.py
index 2ee2d173..c7728e76 100644
--- a/backend/test/api/controller/test_datasets.py
+++ b/backend/test/api/controller/test_datasets.py
@@ -10,6 +10,7 @@
)
from api.application.services.data_service import DataService
from api.application.services.delete_service import DeleteService
+from api.application.services.job_service import JobService
from api.application.services.search_service import SearchService
from api.common.custom_exceptions import (
UserError,
@@ -819,9 +820,12 @@ def test_returns_error_response_when_domain_uppercase(self):
"details": ["domain -> was required to be lowercase only."]
}
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch.object(DataService, "query_data")
def test_call_service_with_only_domain_dataset_when_no_json_provided(
- self, mock_query_method
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
):
query_url = f"{BASE_API_PATH}/datasets/raw/mydomain/mydataset/query?version=1"
@@ -833,8 +837,13 @@ def test_call_service_with_only_domain_dataset_when_no_json_provided(
DatasetMetadata("raw", "mydomain", "mydataset", 1), Query()
)
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch.object(DataService, "query_data")
- def test_call_service_with_sql_query_when_json_provided(self, mock_query_method):
+ def test_call_service_with_sql_query_when_json_provided(
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
+ ):
request_json = {"select_columns": ["column1"], "limit": "10"}
query_url = f"{BASE_API_PATH}/datasets/raw/mydomain/mydataset/query?version=1"
@@ -848,10 +857,13 @@ def test_call_service_with_sql_query_when_json_provided(self, mock_query_method)
Query(select_columns=["column1"], limit="10"),
)
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch("api.controller.datasets.construct_dataset_metadata")
@patch.object(DataService, "query_data")
def test_call_service_with_latest_version_when_none_provided(
- self, mock_query_method, mock_construct_metadata
+ self, mock_query_method, mock_construct_metadata, mock_get_subject_id, mock_create_query_job, mock_succeed_query
):
mock_construct_metadata.return_value = DatasetMetadata(
"raw", "mydomain", "mydataset", 32
@@ -864,9 +876,12 @@ def test_call_service_with_latest_version_when_none_provided(
DatasetMetadata("raw", "mydomain", "mydataset", 32), Query()
)
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch.object(DataService, "query_data")
def test_calls_service_with_sql_query_when_empty_json_values_provided(
- self, mock_query_method
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
):
request_json = {
"select_columns": ["column1"],
@@ -891,8 +906,13 @@ def test_calls_service_with_sql_query_when_empty_json_values_provided(
),
)
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch.object(DataService, "query_data")
- def test_returns_formatted_json_from_query_result(self, mock_query_method):
+ def test_returns_formatted_json_from_query_result(
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
+ ):
mock_query_method.return_value = pd.DataFrame(
{
"column1": [1, 2],
@@ -918,8 +938,13 @@ def test_returns_formatted_json_from_query_result(self, mock_query_method):
"1": {"column1": "2", "column2": "item2", "area": "area_2"},
}
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch.object(DataService, "query_data")
- def test_request_query_in_csv_is_successful(self, mock_query_method):
+ def test_request_query_in_csv_is_successful(
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
+ ):
mock_query_method.return_value = pd.DataFrame(
{
"column1": [1, 2],
@@ -937,9 +962,12 @@ def test_request_query_in_csv_is_successful(self, mock_query_method):
assert response.status_code == 200
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch.object(DataService, "query_data")
def test_returns_formatted_json_from_query_if_format_is_not_provided(
- self, mock_query_method
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
):
mock_query_method.return_value = pd.DataFrame(
{
@@ -961,8 +989,13 @@ def test_returns_formatted_json_from_query_if_format_is_not_provided(
"1": {"column1": "2", "column2": "item2", "area": "area_2"},
}
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch.object(DataService, "query_data")
- def test_returns_204_if_dataframe_is_empty(self, mock_query_method):
+ def test_returns_204_if_dataframe_is_empty(
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
+ ):
mock_query_method.return_value = pd.DataFrame(
{
"column1": [],
@@ -983,9 +1016,12 @@ def test_returns_204_if_dataframe_is_empty(self, mock_query_method):
== "No rows were returned. Either there is no data or the query is too limiting."
)
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
@patch.object(DataService, "query_data")
def test_returns_error_from_query_request_when_format_is_unsupported(
- self, mock_query_method
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
):
mock_query_method.return_value = pd.DataFrame(
{
@@ -1007,6 +1043,25 @@ def test_returns_error_from_query_request_when_format_is_unsupported(
"details": "Provided value for Accept header parameter [text/plain] is not supported. Supported formats: application/json, text/csv, application/octet-stream"
}
+ @patch.object(JobService, "succeed_query")
+ @patch.object(JobService, "create_query_job")
+ @patch("api.controller.datasets.get_subject_id")
+ @patch.object(DataService, "query_data")
+ def test_creates_audit_job_on_successful_query(
+ self, mock_query_method, mock_get_subject_id, mock_create_query_job, mock_succeed_query
+ ):
+ mock_query_method.return_value = pd.DataFrame({"col": [1]})
+ mock_get_subject_id.return_value = "subject_id"
+ fake_job = mock_create_query_job.return_value
+
+ query_url = f"{BASE_API_PATH}/datasets/raw/mydomain/mydataset/query?version=1"
+ self.client.post(query_url, headers={"Authorization": "Bearer test-token"})
+
+ mock_create_query_job.assert_called_once_with(
+ "subject_id", DatasetMetadata("raw", "mydomain", "mydataset", 1)
+ )
+ mock_succeed_query.assert_called_once_with(fake_job, url=None)
+
@pytest.mark.parametrize(
"input_key", ["select_column", "invalid_key", "another_invalid_key"]
)
diff --git a/backend/test/api/test_entry.py b/backend/test/api/test_entry.py
index f4947f14..ca50182f 100644
--- a/backend/test/api/test_entry.py
+++ b/backend/test/api/test_entry.py
@@ -45,13 +45,16 @@ def test_gets_permissions_for_ui(self, mock_permissions_service):
class TestDatasetsUI(BaseClientTest):
+ @patch("api.entry.data_service")
@patch("api.entry.get_subject_id")
@patch.object(DatasetAccessEvaluator, "get_authorised_datasets")
def test_gets_datasets_for_ui_write(
- self, mock_get_authorised_datasets, mock_get_subject_id
+ self, mock_get_authorised_datasets, mock_get_subject_id, mock_data_service
):
subject_id = "123abc"
mock_get_subject_id.return_value = subject_id
+ mock_data_service.get_last_updated_time.return_value = None
+ mock_data_service.get_last_uploader.return_value = None
mock_get_authorised_datasets.return_value = [
DatasetMetadata("layer", "domain1", "datset1", 1),
@@ -66,13 +69,16 @@ def test_gets_datasets_for_ui_write(
mock_get_authorised_datasets.assert_called_once_with(subject_id, Action.WRITE)
assert response.status_code == 200
+ @patch("api.entry.data_service")
@patch("api.entry.get_subject_id")
@patch.object(DatasetAccessEvaluator, "get_authorised_datasets")
def test_gets_datasets_for_ui_read(
- self, mock_get_authorised_datasets, mock_get_subject_id
+ self, mock_get_authorised_datasets, mock_get_subject_id, mock_data_service
):
subject_id = "123abc"
mock_get_subject_id.return_value = subject_id
+ mock_data_service.get_last_updated_time.return_value = None
+ mock_data_service.get_last_uploader.return_value = None
mock_get_authorised_datasets.return_value = [
DatasetMetadata("layer", "domain1", "datset1", 1),
@@ -148,6 +154,7 @@ def test_calls_methods_with_expected_arguments(
assert response.status_code == 200
assert response.json() == {
"error_message": None,
+ "username": None,
"can_manage_users": True,
"can_upload": True,
"can_download": True,
@@ -173,6 +180,7 @@ def test_calls_methods_with_expected_arguments_when_user_error(
assert response.status_code == 200
assert response.json() == {
"error_message": "You have not been granted relevant permissions. Please speak to your system administrator.",
+ "username": None,
}
@patch("api.entry.get_subject_id")
@@ -193,6 +201,7 @@ def test_calls_methods_with_expected_arguments_when_aws_error(
assert response.status_code == 200
assert response.json() == {
"error_message": "a custom message",
+ "username": None,
}
@patch("api.entry.get_subject_id")
@@ -213,4 +222,5 @@ def test_calls_methods_with_expected_arguments_when_no_permissions(
assert response.status_code == 200
assert response.json() == {
"error_message": "You have not been granted relevant permissions. Please speak to your system administrator.",
+ "username": None,
}
diff --git a/docs/diagrams/ui_create_schema.png b/docs/diagrams/ui_create_schema.png
index abfd8cac..591289d4 100644
Binary files a/docs/diagrams/ui_create_schema.png and b/docs/diagrams/ui_create_schema.png differ
diff --git a/docs/diagrams/ui_create_user.png b/docs/diagrams/ui_create_user.png
index d1dd5fa6..fa26f6ac 100644
Binary files a/docs/diagrams/ui_create_user.png and b/docs/diagrams/ui_create_user.png differ
diff --git a/docs/diagrams/ui_download_data.png b/docs/diagrams/ui_download_data.png
index 63481db1..a2cee60c 100644
Binary files a/docs/diagrams/ui_download_data.png and b/docs/diagrams/ui_download_data.png differ
diff --git a/docs/frontend/usage.md b/docs/frontend/usage.md
index a4cb5338..9d9f15eb 100644
--- a/docs/frontend/usage.md
+++ b/docs/frontend/usage.md
@@ -4,25 +4,32 @@ The rAPId Frontend is a NextJS static site that serves as a user friendly wrappe
The Frontend provides easy access to the core actions within rAPId such as the ability to create schemas, upload and download data, as well as handling common user and client management.
+Navigation is handled by a sidebar with the following sections, shown based on your permissions:
+
+- **Catalog** — browse, search and open datasets you can read.
+- **Add Dataset** — create a new schema from a sample file.
+- **Jobs** — view the status of upload and query jobs.
+- **User Admin** — create and modify users and clients.
+
> ## Demo Frontend coming soon!
>
> In lieu of a demo Frontend for you to use, here are some screenshots that demonstrate the functionality available.
-## Creating Users
+## Managing Users
-You can easily create users and set their permissions.
+From the **User Admin** section you can browse all users and clients in a searchable, filterable table. Select a subject to modify its permissions, or use **Create subject** to add a new user or client and set their permissions.

## Creating Schemas
-You can create a schema by specifying just the `sensitivity`, `layer`, `domain` and `dataset title` then uploading an example file the data. rAPId will then infer the column names and types from the data and present them to you for review. You can then tweak them before submitting the schema for creation.
+From the **Add Dataset** section you can create a schema by specifying just the `sensitivity`, `layer`, `domain` and `dataset title` then uploading an example file of the data. rAPId will then infer the column names and types from the data and present them to you for review. You can then tweak them before submitting the schema for creation.

## Downloading Data
-If a user has `READ` access to a dataset, they download it by selecting it from the dropdown and clicking through.
+If a user has `READ` access to a dataset, they can open it from the **Catalog** and use the **Download** action on the dataset page to query and download its contents.

diff --git a/frontend/.storybook/main.js b/frontend/.storybook/main.mjs
similarity index 66%
rename from frontend/.storybook/main.js
rename to frontend/.storybook/main.mjs
index 479ee674..dc29ffd6 100644
--- a/frontend/.storybook/main.js
+++ b/frontend/.storybook/main.mjs
@@ -1,13 +1,14 @@
-const path = require('path')
+import path from 'path'
+import { fileURLToPath } from 'url'
-module.exports = {
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
+
+const config = {
stories: [
- '../src/components/**/*.stories.mdx',
'../src/components/**/*.stories.@(js|jsx|ts|tsx)'
],
addons: [
'@storybook/addon-links',
- 'storybook-addon-designs',
'@storybook/addon-a11y',
'@storybook/addon-docs'
],
@@ -22,8 +23,7 @@ module.exports = {
typescript: {
check: true
},
- webpackFinal: async (config, { configType }) => {
- config.resolve.modules = [path.resolve(__dirname, '..'), 'node_modules']
+ viteFinal: async (config) => {
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, '../src/')
@@ -31,3 +31,5 @@ module.exports = {
return config
}
}
+
+export default config
diff --git a/frontend/.storybook/manager.js b/frontend/.storybook/manager.js
index e520f405..b0751f81 100644
--- a/frontend/.storybook/manager.js
+++ b/frontend/.storybook/manager.js
@@ -1,4 +1,4 @@
-import { addons } from '@storybook/addons'
+import { addons } from 'storybook/manager-api'
import theme from './theme'
addons.setConfig({
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 6ac78d0d..efc12a80 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -20,10 +20,9 @@
"@types/react-dom": "^19.0.0",
"dedent": "^1.5.1",
"eslint": "^9.0.0",
- "eslint-config-next": "^16.0.0",
- "jest-cli": "^29.6.4",
+ "eslint-config-next": "^16.2.3",
"memory-cache": "^0.2.0",
- "next": "^16.0.0",
+ "next": "^16.2.3",
"playwright": "^1.37.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
@@ -35,11 +34,11 @@
"@aws-sdk/client-secrets-manager": "^3.978.0",
"@babel/core": "^7.26.10",
"@playwright/test": "^1.51.0",
- "@storybook/addon-a11y": "^10.2.2",
- "@storybook/addon-docs": "^10.2.2",
- "@storybook/addon-links": "^10.2.2",
- "@storybook/nextjs-vite": "10.2.2",
- "@storybook/react": "^10.2.2",
+ "@storybook/addon-a11y": "^10.2.10",
+ "@storybook/addon-docs": "^10.2.10",
+ "@storybook/addon-links": "^10.2.10",
+ "@storybook/nextjs-vite": "10.2.10",
+ "@storybook/react": "^10.2.10",
"@svgr/webpack": "^6.5.1",
"@tanstack/react-query-devtools": "^4.33.0",
"@testing-library/jest-dom": "^5.16.5",
@@ -52,18 +51,18 @@
"dotenv": "^16.4.7",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-jest-dom": "^5.0.0",
- "eslint-plugin-storybook": "^10.2.2",
+ "eslint-plugin-storybook": "^10.2.10",
"eslint-plugin-testing-library": "^6.0.0",
- "jest": "^29.6.4",
- "jest-environment-jsdom": "^29.3.1",
+ "jest": "^30.2.0",
+ "jest-cli": "^30.2.0",
+ "jest-environment-jsdom": "^30.2.0",
"jest-fetch-mock": "^3.0.3",
"prettier": "^2.8.1",
- "pretty-format": "^29.3.1",
- "storybook": "^10.2.2",
- "storybook-addon-designs": "^6.3.1",
- "typescript": "5.1.6",
+ "pretty-format": "^30.2.0",
+ "storybook": "^10.2.10",
+ "typescript": "^5.4.0",
"uuid": "^13.0.0",
- "vite": "^7.0.0"
+ "vite": "^7.3.2"
}
},
"node_modules/@adobe/css-tools": {
@@ -73,6 +72,27 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/@aws-crypto/sha256-browser": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
@@ -939,14 +959,14 @@
"license": "0BSD"
},
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.972.2",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.2.tgz",
- "integrity": "sha512-jGOOV/bV1DhkkUhHiZ3/1GZ67cZyOXaDb7d1rYD6ZiXf5V9tBNOcgqXwRRPvrCbYaFRa1pPMFb3ZjqjWpR3YfA==",
+ "version": "3.972.17",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.17.tgz",
+ "integrity": "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^4.12.0",
- "fast-xml-parser": "5.2.5",
+ "@smithy/types": "^4.14.0",
+ "fast-xml-parser": "5.5.8",
"tslib": "^2.6.2"
},
"engines": {
@@ -1195,6 +1215,7 @@
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
"integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -1421,6 +1442,7 @@
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
"integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -1433,6 +1455,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
"integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -1445,6 +1468,7 @@
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
"integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.12.13"
@@ -1457,6 +1481,7 @@
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
"integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
@@ -1488,6 +1513,7 @@
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz",
"integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.28.6"
@@ -1503,6 +1529,7 @@
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
"integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
@@ -1515,6 +1542,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
"integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -1527,6 +1555,7 @@
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz",
"integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.28.6"
@@ -1542,6 +1571,7 @@
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
"integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
@@ -1554,6 +1584,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
"integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -1566,6 +1597,7 @@
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
"integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
@@ -1578,6 +1610,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
"integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -1590,6 +1623,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
"integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -1602,6 +1636,7 @@
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
"integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -1614,6 +1649,7 @@
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
"integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
@@ -1629,6 +1665,7 @@
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
"integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
@@ -1644,6 +1681,7 @@
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz",
"integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.28.6"
@@ -2832,8 +2870,124 @@
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true,
"license": "MIT"
},
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
+ "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
+ "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/color-helpers": "^5.1.0",
+ "@csstools/css-calc": "^2.1.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@emnapi/core": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz",
@@ -3652,30 +3806,6 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@figspec/components": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@figspec/components/-/components-1.0.3.tgz",
- "integrity": "sha512-fBwHzJ4ouuOUJEi+yBZIrOy+0/fAjB3AeTcIHTT1PRxLz8P63xwC7R0EsIJXhScIcc+PljGmqbbVJCjLsnaGYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lit": "^2.1.3"
- }
- },
- "node_modules/@figspec/react": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@figspec/react/-/react-1.0.4.tgz",
- "integrity": "sha512-jaPvkIef4d6NjsRiw91OZabrfdPH9FtoPGYcY5mpXjYEcdUqIq1aHtLq3SkMVyVysEapTEJ6yS8amy93MyXBEQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@figspec/components": "^1.0.1",
- "@lit-labs/react": "^1.0.2"
- },
- "peerDependencies": {
- "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
- }
- },
"node_modules/@floating-ui/core": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.4.tgz",
@@ -4237,29 +4367,6 @@
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/@isaacs/balanced-match": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
- "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "20 || >=22"
- }
- },
- "node_modules/@isaacs/brace-expansion": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
- "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@isaacs/balanced-match": "^4.0.1"
- },
- "engines": {
- "node": "20 || >=22"
- }
- },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -4323,13 +4430,13 @@
}
},
"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
- "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "ansi-regex": "^6.0.1"
+ "ansi-regex": "^6.2.2"
},
"engines": {
"node": ">=12"
@@ -4360,6 +4467,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
"integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"camelcase": "^5.3.1",
@@ -4376,6 +4484,7 @@
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4385,6 +4494,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
@@ -4398,6 +4508,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
@@ -4410,6 +4521,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
@@ -4425,6 +4537,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
@@ -4434,88 +4547,70 @@
}
},
"node_modules/@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz",
+ "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/@jest/console": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz",
- "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz",
+ "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "chalk": "^4.0.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
+ "chalk": "^4.1.2",
+ "jest-message-util": "30.3.0",
+ "jest-util": "30.3.0",
"slash": "^3.0.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/console/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/core": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz",
- "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz",
+ "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/reporters": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
+ "@jest/console": "30.3.0",
+ "@jest/pattern": "30.0.1",
+ "@jest/reporters": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "jest-changed-files": "^29.7.0",
- "jest-config": "^29.7.0",
- "jest-haste-map": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-resolve-dependencies": "^29.7.0",
- "jest-runner": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "jest-watcher": "^29.7.0",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "strip-ansi": "^6.0.0"
+ "ansi-escapes": "^4.3.2",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "exit-x": "^0.2.2",
+ "graceful-fs": "^4.2.11",
+ "jest-changed-files": "30.3.0",
+ "jest-config": "30.3.0",
+ "jest-haste-map": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.3.0",
+ "jest-resolve-dependencies": "30.3.0",
+ "jest-runner": "30.3.0",
+ "jest-runtime": "30.3.0",
+ "jest-snapshot": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0",
+ "jest-watcher": "30.3.0",
+ "pretty-format": "30.3.0",
+ "slash": "^3.0.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
"node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
@@ -4526,30 +4621,10 @@
}
}
},
- "node_modules/@jest/core/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/@jest/diff-sequences": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz",
- "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz",
+ "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4557,51 +4632,67 @@
}
},
"node_modules/@jest/environment": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
- "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz",
+ "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
+ "@jest/fake-timers": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "jest-mock": "^29.7.0"
+ "jest-mock": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jest/environment/node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+ "node_modules/@jest/environment-jsdom-abstract": {
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.3.0.tgz",
+ "integrity": "sha512-0hNFs5N6We3DMCwobzI0ydhkY10sT1tZSC0AAiy+0g2Dt/qEWgrcV5BrMxPczhe41cxW4qm6X+jqZaUdpZIajA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/environment": "30.3.0",
+ "@jest/fake-timers": "30.3.0",
+ "@jest/types": "30.3.0",
+ "@types/jsdom": "^21.1.7",
"@types/node": "*",
- "jest-util": "^29.7.0"
+ "jest-mock": "30.3.0",
+ "jest-util": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "canvas": "^3.0.0",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
}
},
"node_modules/@jest/expect": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz",
- "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz",
+ "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "expect": "^29.7.0",
- "jest-snapshot": "^29.7.0"
+ "expect": "30.3.0",
+ "jest-snapshot": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/expect-utils": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz",
- "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz",
+ "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4611,133 +4702,22 @@
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jest/expect/node_modules/@jest/expect-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
- "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
- "license": "MIT",
- "dependencies": {
- "jest-get-type": "^29.6.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/expect/node_modules/expect": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
- "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
- "license": "MIT",
- "dependencies": {
- "@jest/expect-utils": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/expect/node_modules/jest-diff": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
- "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "diff-sequences": "^29.6.3",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/expect/node_modules/jest-matcher-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
- "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "jest-diff": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/expect/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/@jest/fake-timers": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
- "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@sinonjs/fake-timers": "^10.0.2",
- "@types/node": "*",
- "jest-message-util": "^29.7.0",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/fake-timers/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/fake-timers/node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz",
+ "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "30.3.0",
+ "@sinonjs/fake-timers": "^15.0.0",
"@types/node": "*",
- "jest-util": "^29.7.0"
+ "jest-message-util": "30.3.0",
+ "jest-mock": "30.3.0",
+ "jest-util": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/get-type": {
@@ -4751,32 +4731,19 @@
}
},
"node_modules/@jest/globals": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz",
- "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/expect": "^29.7.0",
- "@jest/types": "^29.6.3",
- "jest-mock": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/globals/node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz",
+ "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-util": "^29.7.0"
+ "@jest/environment": "30.3.0",
+ "@jest/expect": "30.3.0",
+ "@jest/types": "30.3.0",
+ "jest-mock": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/pattern": {
@@ -4793,49 +4760,39 @@
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jest/pattern/node_modules/jest-regex-util": {
- "version": "30.0.1",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz",
- "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
"node_modules/@jest/reporters": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz",
- "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz",
+ "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
+ "@jest/console": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
+ "@jridgewell/trace-mapping": "^0.3.25",
"@types/node": "*",
- "chalk": "^4.0.0",
- "collect-v8-coverage": "^1.0.0",
- "exit": "^0.1.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
+ "chalk": "^4.1.2",
+ "collect-v8-coverage": "^1.0.2",
+ "exit-x": "^0.2.2",
+ "glob": "^10.5.0",
+ "graceful-fs": "^4.2.11",
"istanbul-lib-coverage": "^3.0.0",
"istanbul-lib-instrument": "^6.0.0",
"istanbul-lib-report": "^3.0.0",
- "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-lib-source-maps": "^5.0.0",
"istanbul-reports": "^3.1.3",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-worker": "^29.7.0",
+ "jest-message-util": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-worker": "30.3.0",
"slash": "^3.0.0",
- "string-length": "^4.0.1",
- "strip-ansi": "^6.0.0",
+ "string-length": "^4.0.2",
"v8-to-istanbul": "^9.0.1"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
"node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
@@ -4846,161 +4803,207 @@
}
}
},
- "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
- "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
- "license": "BSD-3-Clause",
+ "node_modules/@jest/reporters/node_modules/brace-expansion": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/core": "^7.23.9",
- "@babel/parser": "^7.23.9",
- "@istanbuljs/schema": "^0.1.3",
- "istanbul-lib-coverage": "^3.2.0",
- "semver": "^7.5.4"
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@jest/reporters/node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
},
- "engines": {
- "node": ">=10"
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/@jest/reporters/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
- "license": "MIT",
+ "node_modules/@jest/reporters/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@jest/reporters/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
+ "brace-expansion": "^2.0.2"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/@jest/reporters/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
+ "node_modules/@jest/reporters/node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "version": "30.0.5",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
+ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.34.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/snapshot-utils": {
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz",
+ "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@sinclair/typebox": "^0.27.8"
+ "@jest/types": "30.3.0",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "natural-compare": "^1.4.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/source-map": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
- "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz",
+ "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.18",
- "callsites": "^3.0.0",
- "graceful-fs": "^4.2.9"
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "callsites": "^3.1.0",
+ "graceful-fs": "^4.2.11"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/test-result": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz",
- "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz",
+ "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "collect-v8-coverage": "^1.0.0"
+ "@jest/console": "30.3.0",
+ "@jest/types": "30.3.0",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "collect-v8-coverage": "^1.0.2"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/test-sequencer": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz",
- "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz",
+ "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/test-result": "^29.7.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
+ "@jest/test-result": "30.3.0",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.3.0",
"slash": "^3.0.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/transform": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
- "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz",
+ "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/types": "^29.6.3",
- "@jridgewell/trace-mapping": "^0.3.18",
- "babel-plugin-istanbul": "^6.1.1",
- "chalk": "^4.0.0",
+ "@babel/core": "^7.27.4",
+ "@jest/types": "30.3.0",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "babel-plugin-istanbul": "^7.0.1",
+ "chalk": "^4.1.2",
"convert-source-map": "^2.0.0",
"fast-json-stable-stringify": "^2.1.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.7.0",
- "micromatch": "^4.0.4",
- "pirates": "^4.0.4",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.3.0",
+ "jest-regex-util": "30.0.1",
+ "jest-util": "30.3.0",
+ "pirates": "^4.0.7",
"slash": "^3.0.0",
- "write-file-atomic": "^4.0.2"
+ "write-file-atomic": "^5.0.1"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@jest/types": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
- "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz",
+ "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/schemas": "^29.6.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
+ "@jest/pattern": "30.0.1",
+ "@jest/schemas": "30.0.5",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
"@types/node": "*",
- "@types/yargs": "^17.0.8",
- "chalk": "^4.0.0"
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/@joshwooding/vite-plugin-react-docgen-typescript": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.6.3.tgz",
- "integrity": "sha512-9TGZuAX+liGkNKkwuo3FYJu7gHWT0vkBcf7GkOe7s7fmC19XwH/4u5u7sDIFrMooe558ORcmuBvBz7Ur5PlbHw==",
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.6.4.tgz",
+ "integrity": "sha512-6PyZBYKnnVNqOSB0YFly+62R7dmov8segT27A+RVTBVd4iAE6kbW9QBJGlyR2yG4D4ohzhZSTIu7BK1UTtmFFA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "glob": "^11.1.0",
+ "glob": "^13.0.1",
"react-docgen-typescript": "^2.2.2"
},
"peerDependencies": {
@@ -5013,46 +5016,6 @@
}
}
},
- "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/glob": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
- "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "foreground-child": "^3.3.1",
- "jackspeak": "^4.1.1",
- "minimatch": "^10.1.1",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^2.0.0"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "engines": {
- "node": "20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/minimatch": {
- "version": "10.1.1",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
- "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/brace-expansion": "^5.0.0"
- },
- "engines": {
- "node": "20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -5098,30 +5061,6 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@lit-labs/react": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-1.2.1.tgz",
- "integrity": "sha512-DiZdJYFU0tBbdQkfwwRSwYyI/mcWkg3sWesKRsHUd4G+NekTmmeq9fzsurvcKTNVa0comNljwtg4Hvi1ds3V+A==",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/@lit-labs/ssr-dom-shim": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.5.1.tgz",
- "integrity": "sha512-Aou5UdlSpr5whQe8AA/bZG0jMj96CoJIWbGfZ91qieWu5AWUMKw8VR/pAkQkJYvBNhmCcWnZlyyk5oze8JIqYA==",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/@lit/reactive-element": {
- "version": "1.6.3",
- "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz",
- "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@lit-labs/ssr-dom-shim": "^1.0.0"
- }
- },
"node_modules/@mdx-js/react": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz",
@@ -5452,24 +5391,24 @@
}
},
"node_modules/@next/env": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.6.tgz",
- "integrity": "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.3.tgz",
+ "integrity": "sha512-ZWXyj4uNu4GCWQw9cjRxWlbD+33mcDszIo9iQxFnBX3Wmgq9ulaSJcl6VhuWx5pCWqqD+9W6Wfz7N0lM5lYPMA==",
"license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.6.tgz",
- "integrity": "sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.3.tgz",
+ "integrity": "sha512-nE/b9mht28XJxjTwKs/yk7w4XTaU3t40UHVAky6cjiijdP/SEy3hGsnQMPxmXPTpC7W4/97okm6fngKnvCqVaA==",
"license": "MIT",
"dependencies": {
"fast-glob": "3.3.1"
}
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.6.tgz",
- "integrity": "sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.3.tgz",
+ "integrity": "sha512-u37KDKTKQ+OQLvY+z7SNXixwo4Q2/IAJFDzU1fYe66IbCE51aDSAzkNDkWmLN0yjTUh4BKBd+hb69jYn6qqqSg==",
"cpu": [
"arm64"
],
@@ -5483,9 +5422,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.6.tgz",
- "integrity": "sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.3.tgz",
+ "integrity": "sha512-gHjL/qy6Q6CG3176FWbAKyKh9IfntKZTB3RY/YOJdDFpHGsUDXVH38U4mMNpHVGXmeYW4wj22dMp1lTfmu/bTQ==",
"cpu": [
"x64"
],
@@ -5499,9 +5438,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.6.tgz",
- "integrity": "sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.3.tgz",
+ "integrity": "sha512-U6vtblPtU/P14Y/b/n9ZY0GOxbbIhTFuaFR7F4/uMBidCi2nSdaOFhA0Go81L61Zd6527+yvuX44T4ksnf8T+Q==",
"cpu": [
"arm64"
],
@@ -5515,9 +5454,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.6.tgz",
- "integrity": "sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.3.tgz",
+ "integrity": "sha512-/YV0LgjHUmfhQpn9bVoGc4x4nan64pkhWR5wyEV8yCOfwwrH630KpvRg86olQHTwHIn1z59uh6JwKvHq1h4QEw==",
"cpu": [
"arm64"
],
@@ -5531,9 +5470,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.6.tgz",
- "integrity": "sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.3.tgz",
+ "integrity": "sha512-/HiWEcp+WMZ7VajuiMEFGZ6cg0+aYZPqCJD3YJEfpVWQsKYSjXQG06vJP6F1rdA03COD9Fef4aODs3YxKx+RDQ==",
"cpu": [
"x64"
],
@@ -5547,9 +5486,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.6.tgz",
- "integrity": "sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.3.tgz",
+ "integrity": "sha512-Kt44hGJfZSefebhk/7nIdivoDr3Ugp5+oNz9VvF3GUtfxutucUIHfIO0ZYO8QlOPDQloUVQn4NVC/9JvHRk9hw==",
"cpu": [
"x64"
],
@@ -5563,9 +5502,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.6.tgz",
- "integrity": "sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.3.tgz",
+ "integrity": "sha512-O2NZ9ie3Tq6xj5Z5CSwBT3+aWAMW2PIZ4egUi9MaWLkwaehgtB7YZjPm+UpcNpKOme0IQuqDcor7BsW6QBiQBw==",
"cpu": [
"arm64"
],
@@ -5579,9 +5518,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.6.tgz",
- "integrity": "sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.3.tgz",
+ "integrity": "sha512-Ibm29/GgB/ab5n7XKqlStkm54qqZE8v2FnijUPBgrd67FWrac45o/RsNlaOWjme/B5UqeWt/8KM4aWBwA1D2Kw==",
"cpu": [
"x64"
],
@@ -5638,6 +5577,30 @@
"node": ">=12.4.0"
}
},
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
+ "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
"node_modules/@playwright/test": {
"version": "1.58.0",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0.tgz",
@@ -5687,17 +5650,10 @@
}
}
},
- "node_modules/@rollup/pluginutils/node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@rollup/pluginutils/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5708,9 +5664,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz",
- "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz",
+ "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==",
"cpu": [
"arm"
],
@@ -5722,9 +5678,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz",
- "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz",
+ "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==",
"cpu": [
"arm64"
],
@@ -5736,9 +5692,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz",
- "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz",
+ "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==",
"cpu": [
"arm64"
],
@@ -5750,9 +5706,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz",
- "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz",
+ "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==",
"cpu": [
"x64"
],
@@ -5764,9 +5720,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz",
- "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz",
+ "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==",
"cpu": [
"arm64"
],
@@ -5778,9 +5734,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz",
- "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz",
+ "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==",
"cpu": [
"x64"
],
@@ -5792,9 +5748,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz",
- "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz",
+ "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==",
"cpu": [
"arm"
],
@@ -5806,9 +5762,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz",
- "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz",
+ "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==",
"cpu": [
"arm"
],
@@ -5820,9 +5776,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz",
- "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz",
+ "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==",
"cpu": [
"arm64"
],
@@ -5834,9 +5790,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz",
- "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz",
+ "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==",
"cpu": [
"arm64"
],
@@ -5848,9 +5804,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz",
- "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz",
+ "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==",
"cpu": [
"loong64"
],
@@ -5862,9 +5818,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz",
- "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz",
+ "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==",
"cpu": [
"loong64"
],
@@ -5876,9 +5832,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz",
- "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz",
+ "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==",
"cpu": [
"ppc64"
],
@@ -5890,9 +5846,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz",
- "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz",
+ "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==",
"cpu": [
"ppc64"
],
@@ -5904,9 +5860,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz",
- "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz",
+ "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==",
"cpu": [
"riscv64"
],
@@ -5918,9 +5874,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz",
- "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz",
+ "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==",
"cpu": [
"riscv64"
],
@@ -5932,9 +5888,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz",
- "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz",
+ "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==",
"cpu": [
"s390x"
],
@@ -5946,9 +5902,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz",
- "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz",
+ "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==",
"cpu": [
"x64"
],
@@ -5960,9 +5916,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz",
- "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz",
+ "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==",
"cpu": [
"x64"
],
@@ -5974,9 +5930,9 @@
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz",
- "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz",
+ "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==",
"cpu": [
"x64"
],
@@ -5988,9 +5944,9 @@
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz",
- "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz",
+ "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==",
"cpu": [
"arm64"
],
@@ -6002,9 +5958,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz",
- "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz",
+ "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==",
"cpu": [
"arm64"
],
@@ -6016,9 +5972,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz",
- "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz",
+ "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==",
"cpu": [
"ia32"
],
@@ -6030,9 +5986,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz",
- "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz",
+ "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==",
"cpu": [
"x64"
],
@@ -6044,9 +6000,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz",
- "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz",
+ "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==",
"cpu": [
"x64"
],
@@ -6064,27 +6020,30 @@
"license": "MIT"
},
"node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
+ "version": "0.34.49",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz",
+ "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@sinonjs/commons": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
"integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"type-detect": "4.0.8"
}
},
"node_modules/@sinonjs/fake-timers": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
- "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
+ "version": "15.3.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz",
+ "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
- "@sinonjs/commons": "^3.0.0"
+ "@sinonjs/commons": "^3.0.1"
}
},
"node_modules/@smithy/abort-controller": {
@@ -6614,9 +6573,9 @@
"license": "0BSD"
},
"node_modules/@smithy/types": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz",
- "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==",
+ "version": "4.14.0",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.0.tgz",
+ "integrity": "sha512-OWgntFLW88kx2qvf/c/67Vno1yuXm/f9M7QFAtVkkO29IJXGBIg0ycEaBTH0kvCtwmvZxRujrgP5a86RvsXJAQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -6981,9 +6940,9 @@
"license": "0BSD"
},
"node_modules/@storybook/addon-a11y": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.2.2.tgz",
- "integrity": "sha512-ukEcTcnFHo9ai9PmAtIZ0FlQrsgeKm2BECdf0HZLE2lXPqFxMG3BJ4GbBlDwQBKxOogiBsQkNEA1DR9D4SLrPA==",
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.3.5.tgz",
+ "integrity": "sha512-5k6lpgfIeLxvNhE8v3wEzdiu73ONKjF4gmH1AHvfqYd8kIVzQJai0KCDxgvqNncXHQhIWkaf1fg6+9hKaYJyaw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6995,20 +6954,20 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^10.2.2"
+ "storybook": "^10.3.5"
}
},
"node_modules/@storybook/addon-docs": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.2.2.tgz",
- "integrity": "sha512-oFvkgihqauSMjDdyLbhVIW47PXoXM4b/OSDVcDkwLr+xyetGdc5s0MHVb7qsHXY1N8dLBmmd630WoDiNKyZcFA==",
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.3.5.tgz",
+ "integrity": "sha512-WuHbxia/o5TX4Rg/IFD0641K5qId/Nk0dxhmAUNoFs5L0+yfZUwh65XOBbzXqrkYmYmcVID4v7cgDRmzstQNkA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@mdx-js/react": "^3.0.0",
- "@storybook/csf-plugin": "10.2.2",
+ "@storybook/csf-plugin": "10.3.5",
"@storybook/icons": "^2.0.1",
- "@storybook/react-dom-shim": "10.2.2",
+ "@storybook/react-dom-shim": "10.3.5",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"ts-dedent": "^2.0.0"
@@ -7018,13 +6977,13 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^10.2.2"
+ "storybook": "^10.3.5"
}
},
"node_modules/@storybook/addon-links": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.2.2.tgz",
- "integrity": "sha512-7Gws8JAm9GLX77xAcRI7i3pntBANV5m9bJJxC4p+sAy+VbwE7PGXLoWvx/E3U0EcFoDGF48aznI/X3JwzqWhSQ==",
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.3.5.tgz",
+ "integrity": "sha512-Xe2wCGZ+hpZ0cDqAIBHk+kPc8nODNbu585ghd5bLrlYJMDVXoNM/fIlkrLgjIDVbfpgeJLUEg7vldJrn+FyOLw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7036,7 +6995,7 @@
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
- "storybook": "^10.2.2"
+ "storybook": "^10.3.5"
},
"peerDependenciesMeta": {
"react": {
@@ -7045,13 +7004,13 @@
}
},
"node_modules/@storybook/builder-vite": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.2.2.tgz",
- "integrity": "sha512-Sy6NnjxaUkl+RD5YxeS5Fe7PqSBBOV4yR6poXwgaeDOCLtj4jJv0Gz1pJLGsIPvJUAeAS/qLQh6hggX1xTJJkg==",
+ "version": "10.2.10",
+ "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.2.10.tgz",
+ "integrity": "sha512-Wd6CYL7LvRRNiXMz977x9u/qMm7nmMw/7Dow2BybQo+Xbfy1KhVjIoZ/gOiG515zpojSozctNrJUbM0+jH1jwg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@storybook/csf-plugin": "10.2.2",
+ "@storybook/csf-plugin": "10.2.10",
"ts-dedent": "^2.0.0"
},
"funding": {
@@ -7059,14 +7018,49 @@
"url": "https://opencollective.com/storybook"
},
"peerDependencies": {
- "storybook": "^10.2.2",
+ "storybook": "^10.2.10",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
+ "node_modules/@storybook/builder-vite/node_modules/@storybook/csf-plugin": {
+ "version": "10.2.10",
+ "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.2.10.tgz",
+ "integrity": "sha512-aFvgaNDAnKMjuyhPK5ialT22pPqMN0XfPBNPeeNVPYztngkdKBa8WFqF/umDd47HxAjebq+vn6uId1xHyOHH3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unplugin": "^2.3.5"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "esbuild": "*",
+ "rollup": "*",
+ "storybook": "^10.2.10",
+ "vite": "*",
+ "webpack": "*"
+ },
+ "peerDependenciesMeta": {
+ "esbuild": {
+ "optional": true
+ },
+ "rollup": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@storybook/csf-plugin": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.2.2.tgz",
- "integrity": "sha512-AKcsobCnLGVagvLra+TNj+O1Lo0DJNeHug/+pxwnae7pbpHJDv6+XFy5MQBJ3Ra+MCbLy54fE5tMwJ7/3CwtXg==",
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.3.5.tgz",
+ "integrity": "sha512-qlEzNKxOjq86pvrbuMwiGD/bylnsXk1dg7ve0j77YFjEEchqtl7qTlrXvFdNaLA89GhW6D/EV6eOCu/eobPDgw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7079,7 +7073,7 @@
"peerDependencies": {
"esbuild": "*",
"rollup": "*",
- "storybook": "^10.2.2",
+ "storybook": "^10.3.5",
"vite": "*",
"webpack": "*"
},
@@ -7117,15 +7111,15 @@
}
},
"node_modules/@storybook/nextjs-vite": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/nextjs-vite/-/nextjs-vite-10.2.2.tgz",
- "integrity": "sha512-f/2KuIONAbPCMYztsFYGCS/wNdXROqLCOWsGiSY/Rwu0KfM5+hTpoA62a27jzsVoTD13RpzKqWeOCXCWcGAg5w==",
+ "version": "10.2.10",
+ "resolved": "https://registry.npmjs.org/@storybook/nextjs-vite/-/nextjs-vite-10.2.10.tgz",
+ "integrity": "sha512-8kXTvfzwK1uZhlKLCy410RHs7Q/lodWsDWVduRMs2PcJzVpnQuDwCb3mr8DvRMJDglLRSOEZkOG6W6ymFtITVA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@storybook/builder-vite": "10.2.2",
- "@storybook/react": "10.2.2",
- "@storybook/react-vite": "10.2.2",
+ "@storybook/builder-vite": "10.2.10",
+ "@storybook/react": "10.2.10",
+ "@storybook/react-vite": "10.2.10",
"styled-jsx": "5.1.6",
"vite-plugin-storybook-nextjs": "^3.1.9"
},
@@ -7137,7 +7131,7 @@
"next": "^14.1.0 || ^15.0.0 || ^16.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
- "storybook": "^10.2.2",
+ "storybook": "^10.2.10",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
},
"peerDependenciesMeta": {
@@ -7146,15 +7140,15 @@
}
}
},
- "node_modules/@storybook/react": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.2.2.tgz",
- "integrity": "sha512-BpaeaU7ydbqcR4xctJShNkZg5LevZDoD5PuZBuJrDhY1+iimGhLXyeXPakb3QszBoKi56brdXjecJNbkO7M97Q==",
+ "node_modules/@storybook/nextjs-vite/node_modules/@storybook/react": {
+ "version": "10.2.10",
+ "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.2.10.tgz",
+ "integrity": "sha512-PcsChzPI8lhllB9exV7nFb96093i6sTwIl0jpPjaTFPQCRoueR9E/YeP3qSKQL9xt4cmii0cW7F0RUx25rW93Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/global": "^5.0.0",
- "@storybook/react-dom-shim": "10.2.2",
+ "@storybook/react-dom-shim": "10.2.10",
"react-docgen": "^8.0.2"
},
"funding": {
@@ -7164,7 +7158,51 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
- "storybook": "^10.2.2",
+ "storybook": "^10.2.10",
+ "typescript": ">= 4.9.x"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/nextjs-vite/node_modules/@storybook/react-dom-shim": {
+ "version": "10.2.10",
+ "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.2.10.tgz",
+ "integrity": "sha512-TmBrhyLHn8B8rvDHKk5uW5BqzO1M1T+fqFNWg88NIAJOoyX4Uc90FIJjDuN1OJmWKGwB5vLmPwaKBYsTe1yS+w==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "storybook": "^10.2.10"
+ }
+ },
+ "node_modules/@storybook/react": {
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.3.5.tgz",
+ "integrity": "sha512-tpLTLaVGoA6fLK3ReyGzZUricq7lyPaV2hLPpj5wqdXLV/LpRtAHClUpNoPDYSBjlnSjL81hMZijbkGC3mA+gw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/global": "^5.0.0",
+ "@storybook/react-dom-shim": "10.3.5",
+ "react-docgen": "^8.0.2",
+ "react-docgen-typescript": "^2.2.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "storybook": "^10.3.5",
"typescript": ">= 4.9.x"
},
"peerDependenciesMeta": {
@@ -7174,9 +7212,9 @@
}
},
"node_modules/@storybook/react-dom-shim": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.2.2.tgz",
- "integrity": "sha512-l07S645SbVHEhDiMZLA1ft6EV2VwO19O94pom8yHVNZcjZeCEFYo+W4/QW515XgBigE7RpRDqhKwo5yzHsoadA==",
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.3.5.tgz",
+ "integrity": "sha512-Gw8R7XZm0zSUH0XAuxlQJhmizsLzyD6x00KOlP6l7oW9eQHXGfxg3seNDG3WrSAcW07iP1/P422kuiriQlOv7g==",
"dev": true,
"license": "MIT",
"funding": {
@@ -7186,20 +7224,20 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
- "storybook": "^10.2.2"
+ "storybook": "^10.3.5"
}
},
"node_modules/@storybook/react-vite": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.2.2.tgz",
- "integrity": "sha512-AChXIaC/P9fJGqEC33ZBt429XyJqVoryWwv28zVhGNmysYaxal+4NAettXpg31oGjGJQrpxcmvOOPLErVdoCgg==",
+ "version": "10.2.10",
+ "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.2.10.tgz",
+ "integrity": "sha512-C652GhZHXURi+gFqqLKmZPskEq1FQto4VCf/eQea2exmdVS0nOB+FFWQZNCivX6mpkDHza8UxRZNFpDB0mWcJQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@joshwooding/vite-plugin-react-docgen-typescript": "^0.6.3",
+ "@joshwooding/vite-plugin-react-docgen-typescript": "^0.6.4",
"@rollup/pluginutils": "^5.0.2",
- "@storybook/builder-vite": "10.2.2",
- "@storybook/react": "10.2.2",
+ "@storybook/builder-vite": "10.2.10",
+ "@storybook/react": "10.2.10",
"empathic": "^2.0.0",
"magic-string": "^0.30.0",
"react-docgen": "^8.0.0",
@@ -7213,30 +7251,51 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
- "storybook": "^10.2.2",
+ "storybook": "^10.2.10",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
- "node_modules/@storybook/react-vite/node_modules/react-docgen": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.2.tgz",
- "integrity": "sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==",
+ "node_modules/@storybook/react-vite/node_modules/@storybook/react": {
+ "version": "10.2.10",
+ "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.2.10.tgz",
+ "integrity": "sha512-PcsChzPI8lhllB9exV7nFb96093i6sTwIl0jpPjaTFPQCRoueR9E/YeP3qSKQL9xt4cmii0cW7F0RUx25rW93Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.28.0",
- "@babel/traverse": "^7.28.0",
- "@babel/types": "^7.28.2",
- "@types/babel__core": "^7.20.5",
- "@types/babel__traverse": "^7.20.7",
- "@types/doctrine": "^0.0.9",
- "@types/resolve": "^1.20.2",
- "doctrine": "^3.0.0",
- "resolve": "^1.22.1",
- "strip-indent": "^4.0.0"
+ "@storybook/global": "^5.0.0",
+ "@storybook/react-dom-shim": "10.2.10",
+ "react-docgen": "^8.0.2"
},
- "engines": {
- "node": "^20.9.0 || >=22"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "storybook": "^10.2.10",
+ "typescript": ">= 4.9.x"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/react-vite/node_modules/@storybook/react-dom-shim": {
+ "version": "10.2.10",
+ "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.2.10.tgz",
+ "integrity": "sha512-TmBrhyLHn8B8rvDHKk5uW5BqzO1M1T+fqFNWg88NIAJOoyX4Uc90FIJjDuN1OJmWKGwB5vLmPwaKBYsTe1yS+w==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "storybook": "^10.2.10"
}
},
"node_modules/@storybook/react-vite/node_modules/strip-bom": {
@@ -7249,19 +7308,6 @@
"node": ">=4"
}
},
- "node_modules/@storybook/react-vite/node_modules/strip-indent": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz",
- "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@storybook/react-vite/node_modules/tsconfig-paths": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz",
@@ -7277,41 +7323,6 @@
"node": ">=6"
}
},
- "node_modules/@storybook/react/node_modules/react-docgen": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.2.tgz",
- "integrity": "sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.28.0",
- "@babel/traverse": "^7.28.0",
- "@babel/types": "^7.28.2",
- "@types/babel__core": "^7.20.5",
- "@types/babel__traverse": "^7.20.7",
- "@types/doctrine": "^0.0.9",
- "@types/resolve": "^1.20.2",
- "doctrine": "^3.0.0",
- "resolve": "^1.22.1",
- "strip-indent": "^4.0.0"
- },
- "engines": {
- "node": "^20.9.0 || >=22"
- }
- },
- "node_modules/@storybook/react/node_modules/strip-indent": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz",
- "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz",
@@ -7808,26 +7819,6 @@
"@testing-library/dom": ">=7.21.4"
}
},
- "node_modules/@tootallnate/once": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
- "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@trysound/sax": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
- "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/@tybys/wasm-util": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
@@ -7856,6 +7847,7 @@
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
"integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.20.7",
@@ -7869,6 +7861,7 @@
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
"integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.0.0"
@@ -7878,6 +7871,7 @@
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
"integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.1.0",
@@ -7888,6 +7882,7 @@
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
"integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.28.2"
@@ -7924,25 +7919,18 @@
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"license": "MIT"
},
- "node_modules/@types/graceful-fs": {
- "version": "4.1.9",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
- "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
"integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/istanbul-lib-report": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
"integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/istanbul-lib-coverage": "*"
@@ -7952,6 +7940,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
"integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/istanbul-lib-report": "*"
@@ -7968,65 +7957,10 @@
"pretty-format": "^30.0.0"
}
},
- "node_modules/@types/jest/node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.34.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@types/jest/node_modules/@sinclair/typebox": {
- "version": "0.34.48",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
- "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/jest/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@types/jest/node_modules/pretty-format": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
- "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/@types/jest/node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@types/jsdom": {
- "version": "20.0.1",
- "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz",
- "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==",
+ "version": "21.1.7",
+ "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz",
+ "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -8058,6 +7992,7 @@
"version": "20.4.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz",
"integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/parse-json": {
@@ -8118,6 +8053,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/testing-library__jest-dom": {
@@ -8137,13 +8073,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/trusted-types": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
- "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@types/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
@@ -8155,6 +8084,7 @@
"version": "17.0.35",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
"integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/yargs-parser": "*"
@@ -8164,6 +8094,7 @@
"version": "21.0.3",
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
@@ -8292,9 +8223,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -8310,12 +8241,12 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -8435,21 +8366,21 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/@typescript-eslint/parser/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -8660,21 +8591,21 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -8845,6 +8776,13 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/@unrs/resolver-binding-android-arm-eabi": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz",
@@ -9095,13 +9033,12 @@
"win32"
]
},
- "node_modules/abab": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
- "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
- "deprecated": "Use your platform's native atob() and btoa() methods instead",
+ "node_modules/@webcontainer/env": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@webcontainer/env/-/env-1.1.1.tgz",
+ "integrity": "sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==",
"dev": true,
- "license": "BSD-3-Clause"
+ "license": "MIT"
},
"node_modules/acorn": {
"version": "8.15.0",
@@ -9115,30 +9052,6 @@
"node": ">=0.4.0"
}
},
- "node_modules/acorn-globals": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz",
- "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.1.0",
- "acorn-walk": "^8.0.2"
- }
- },
- "node_modules/acorn-globals/node_modules/acorn-walk": {
- "version": "8.3.4",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
- "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -9149,22 +9062,19 @@
}
},
"node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "debug": "4"
- },
"engines": {
- "node": ">= 6.0.0"
+ "node": ">= 14"
}
},
"node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
@@ -9191,6 +9101,7 @@
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"type-fest": "^0.21.3"
@@ -9202,22 +9113,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/ansi-escapes/node_modules/type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -9242,6 +9142,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
@@ -9255,6 +9156,7 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"sprintf-js": "~1.0.2"
@@ -9477,13 +9379,6 @@
"node": ">= 0.4"
}
},
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -9518,24 +9413,25 @@
}
},
"node_modules/babel-jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
- "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz",
+ "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/transform": "^29.7.0",
- "@types/babel__core": "^7.1.14",
- "babel-plugin-istanbul": "^6.1.1",
- "babel-preset-jest": "^29.6.3",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
+ "@jest/transform": "30.3.0",
+ "@types/babel__core": "^7.20.5",
+ "babel-plugin-istanbul": "^7.0.1",
+ "babel-preset-jest": "30.3.0",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
"slash": "^3.0.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
- "@babel/core": "^7.8.0"
+ "@babel/core": "^7.11.0 || ^8.0.0-0"
}
},
"node_modules/babel-loader": {
@@ -9559,34 +9455,36 @@
}
},
"node_modules/babel-plugin-istanbul": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
- "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz",
+ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==",
+ "dev": true,
"license": "BSD-3-Clause",
+ "workspaces": [
+ "test/babel-8"
+ ],
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
"@istanbuljs/load-nyc-config": "^1.0.0",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-instrument": "^5.0.4",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-instrument": "^6.0.2",
"test-exclude": "^6.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=12"
}
},
"node_modules/babel-plugin-jest-hoist": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
- "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz",
+ "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.3.3",
- "@babel/types": "^7.3.3",
- "@types/babel__core": "^7.1.14",
- "@types/babel__traverse": "^7.0.6"
+ "@types/babel__core": "^7.20.5"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/babel-plugin-macros": {
@@ -9650,6 +9548,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz",
"integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/plugin-syntax-async-generators": "^7.8.4",
@@ -9673,19 +9572,20 @@
}
},
"node_modules/babel-preset-jest": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
- "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz",
+ "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "babel-plugin-jest-hoist": "^29.6.3",
- "babel-preset-current-node-syntax": "^1.0.0"
+ "babel-plugin-jest-hoist": "30.3.0",
+ "babel-preset-current-node-syntax": "^1.2.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
- "@babel/core": "^7.0.0"
+ "@babel/core": "^7.11.0 || ^8.0.0-beta.1"
}
},
"node_modules/balanced-match": {
@@ -9728,9 +9628,9 @@
"license": "MIT"
},
"node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
+ "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -9786,6 +9686,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
"integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
"license": "Apache-2.0",
"dependencies": {
"node-int64": "^0.4.0"
@@ -9873,6 +9774,7 @@
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -9938,6 +9840,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -9954,9 +9857,10 @@
}
},
"node_modules/ci-info": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz",
+ "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -9969,9 +9873,10 @@
}
},
"node_modules/cjs-module-lexer": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
- "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz",
+ "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/client-only": {
@@ -9984,6 +9889,7 @@
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
@@ -10007,6 +9913,7 @@
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"iojs": ">= 1.0.0",
@@ -10017,6 +9924,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz",
"integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==",
+ "dev": true,
"license": "MIT"
},
"node_modules/color-convert": {
@@ -10037,19 +9945,6 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
@@ -10121,27 +10016,6 @@
"node": ">=10"
}
},
- "node_modules/create-jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
- "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==",
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "jest-config": "^29.7.0",
- "jest-util": "^29.7.0",
- "prompts": "^2.0.1"
- },
- "bin": {
- "create-jest": "bin/create-jest.js"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/cross-fetch": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
@@ -10240,33 +10114,20 @@
"node": ">=8.0.0"
}
},
- "node_modules/cssom": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
- "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/cssstyle": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
- "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
+ "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "cssom": "~0.3.6"
+ "@asamuzakjp/css-color": "^3.2.0",
+ "rrweb-cssom": "^0.8.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=18"
}
},
- "node_modules/cssstyle/node_modules/cssom": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
- "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
@@ -10280,18 +10141,17 @@
"license": "BSD-2-Clause"
},
"node_modules/data-urls": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz",
- "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "abab": "^2.0.6",
- "whatwg-mimetype": "^3.0.0",
- "whatwg-url": "^11.0.0"
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/data-view-buffer": {
@@ -10443,6 +10303,7 @@
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -10525,16 +10386,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -10549,20 +10400,12 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
"integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
- "node_modules/diff-sequences": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
- "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -10644,20 +10487,6 @@
],
"license": "BSD-2-Clause"
},
- "node_modules/domexception": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
- "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
- "deprecated": "Use your platform's native DOMException instead",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/domhandler": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
@@ -10772,6 +10601,7 @@
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
"integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -11088,39 +10918,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/escodegen": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
- "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "esprima": "^4.0.1",
- "estraverse": "^5.2.0",
- "esutils": "^2.0.2"
- },
- "bin": {
- "escodegen": "bin/escodegen.js",
- "esgenerate": "bin/esgenerate.js"
- },
- "engines": {
- "node": ">=6.0"
- },
- "optionalDependencies": {
- "source-map": "~0.6.1"
- }
- },
- "node_modules/escodegen/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "optional": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/eslint": {
"version": "9.39.2",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
@@ -11181,12 +10978,12 @@
}
},
"node_modules/eslint-config-next": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.1.6.tgz",
- "integrity": "sha512-vKq40io2B0XtkkNDYyleATwblNt8xuh3FWp8SpSz3pt7P01OkBFlKsJZ2mWt5WsCySlDQLckb1zMY9yE9Qy0LA==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.3.tgz",
+ "integrity": "sha512-Dnkrylzjof/Az7iNoIQJqD18zTxQZcngir19KJaiRsMnnjpQSVoa6aEg/1Q4hQC+cW90uTlgQYadwL1CYNwFWA==",
"license": "MIT",
"dependencies": {
- "@next/eslint-plugin-next": "16.1.6",
+ "@next/eslint-plugin-next": "16.2.3",
"eslint-import-resolver-node": "^0.3.6",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.32.0",
@@ -11509,9 +11306,9 @@
}
},
"node_modules/eslint-plugin-storybook": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.2.2.tgz",
- "integrity": "sha512-fcO4NQicW7QJKAwMccibvjZ+/Riaj3JcQQJybjJ1bbwAJkOv1hcW+0kn/CzcqyB2RRKGAbUN6xZvw5lsa7QCHw==",
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.3.5.tgz",
+ "integrity": "sha512-rEFkfU3ypF44GpB4tiJ9EFDItueoGvGi3+weLHZax2ON2MB7VIDsxdSUGvIU5tMURg+oWYlpzCyLm4TpDq2deA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11519,7 +11316,7 @@
},
"peerDependencies": {
"eslint": ">=8",
- "storybook": "^10.2.2"
+ "storybook": "^10.3.5"
}
},
"node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/scope-manager": {
@@ -11625,9 +11422,9 @@
}
},
"node_modules/eslint-plugin-storybook/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11635,13 +11432,13 @@
}
},
"node_modules/eslint-plugin-storybook/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -11729,6 +11526,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
@@ -11771,6 +11569,13 @@
"node": ">=4.0"
}
},
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -11784,6 +11589,7 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.3",
@@ -11803,133 +11609,34 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "node_modules/exit": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "node_modules/exit-x": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz",
+ "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/expect": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz",
- "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz",
+ "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/expect-utils": "30.2.0",
+ "@jest/expect-utils": "30.3.0",
"@jest/get-type": "30.1.0",
- "jest-matcher-utils": "30.2.0",
- "jest-message-util": "30.2.0",
- "jest-mock": "30.2.0",
- "jest-util": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/expect/node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.34.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/expect/node_modules/@jest/types": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
- "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/pattern": "30.0.1",
- "@jest/schemas": "30.0.5",
- "@types/istanbul-lib-coverage": "^2.0.6",
- "@types/istanbul-reports": "^3.0.4",
- "@types/node": "*",
- "@types/yargs": "^17.0.33",
- "chalk": "^4.1.2"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/expect/node_modules/@sinclair/typebox": {
- "version": "0.34.48",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
- "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/expect/node_modules/ci-info": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz",
- "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/expect/node_modules/jest-mock": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
- "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "jest-util": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/expect/node_modules/jest-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
- "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "30.2.0",
- "@types/node": "*",
- "chalk": "^4.1.2",
- "ci-info": "^4.2.0",
- "graceful-fs": "^4.2.11",
- "picomatch": "^4.0.2"
+ "jest-matcher-utils": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-mock": "30.3.0",
+ "jest-util": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/expect/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -11976,10 +11683,26 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"license": "MIT"
},
+ "node_modules/fast-xml-builder": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz",
+ "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "path-expression-matcher": "^1.1.3"
+ }
+ },
"node_modules/fast-xml-parser": {
- "version": "5.2.5",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz",
- "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==",
+ "version": "5.5.8",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz",
+ "integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==",
"dev": true,
"funding": [
{
@@ -11989,7 +11712,9 @@
],
"license": "MIT",
"dependencies": {
- "strnum": "^2.1.0"
+ "fast-xml-builder": "^1.1.4",
+ "path-expression-matcher": "^1.2.0",
+ "strnum": "^2.2.0"
},
"bin": {
"fxparser": "src/cli/cli.js"
@@ -12008,6 +11733,7 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
"integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
"license": "Apache-2.0",
"dependencies": {
"bser": "2.1.1"
@@ -12072,75 +11798,6 @@
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
}
},
- "node_modules/find-cache-dir/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-cache-dir/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-cache-dir/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/find-cache-dir/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-cache-dir/node_modules/pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "find-up": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
@@ -12177,9 +11834,9 @@
}
},
"node_modules/flatted": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
- "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
+ "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
"license": "ISC"
},
"node_modules/for-each": {
@@ -12227,33 +11884,18 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/form-data": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
- "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "es-set-tostringtag": "^2.1.0",
- "hasown": "^2.0.2",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
"license": "ISC"
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -12324,6 +11966,7 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
@@ -12357,6 +12000,7 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8.0.0"
@@ -12379,6 +12023,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -12417,21 +12062,18 @@
}
},
"node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "license": "ISC",
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
},
"engines": {
- "node": "*"
+ "node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -12449,14 +12091,53 @@
"node": ">=10.13.0"
}
},
- "node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "node_modules/glob/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=18"
- },
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
+ "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.5"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
@@ -12521,6 +12202,7 @@
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/has-bigints": {
@@ -12641,22 +12323,23 @@
"license": "MIT"
},
"node_modules/html-encoding-sniffer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
- "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "whatwg-encoding": "^2.0.0"
+ "whatwg-encoding": "^3.1.1"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/html-tokenize": {
@@ -12676,43 +12359,56 @@
}
},
"node_modules/http-proxy-agent": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@tootallnate/once": "2",
- "agent-base": "6",
- "debug": "4"
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 14"
}
},
"node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "agent-base": "6",
+ "agent-base": "^7.1.2",
"debug": "4"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 14"
}
},
"node_modules/human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=10.17.0"
}
},
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -12751,6 +12447,7 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
"integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"pkg-dir": "^4.2.0",
@@ -12766,70 +12463,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/import-local/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "license": "MIT",
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/import-local/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "license": "MIT",
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/import-local/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "license": "MIT",
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/import-local/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/import-local/node_modules/pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "license": "MIT",
- "dependencies": {
- "find-up": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -12854,6 +12487,7 @@
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
"license": "ISC",
"dependencies": {
"once": "^1.3.0",
@@ -13095,6 +12729,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -13104,6 +12739,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
"integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -13264,6 +12900,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -13408,31 +13045,47 @@
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
"integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=8"
}
},
"node_modules/istanbul-lib-instrument": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
- "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
- "@babel/core": "^7.12.3",
- "@babel/parser": "^7.14.7",
- "@istanbuljs/schema": "^0.1.2",
+ "@babel/core": "^7.23.9",
+ "@babel/parser": "^7.23.9",
+ "@istanbuljs/schema": "^0.1.3",
"istanbul-lib-coverage": "^3.2.0",
- "semver": "^6.3.0"
+ "semver": "^7.5.4"
},
"engines": {
- "node": ">=8"
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/istanbul-lib-report": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
"integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
@@ -13447,6 +13100,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
"integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"semver": "^7.5.3"
@@ -13459,9 +13113,10 @@
}
},
"node_modules/istanbul-lib-report/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -13471,32 +13126,25 @@
}
},
"node_modules/istanbul-lib-source-maps": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
"debug": "^4.1.1",
- "istanbul-lib-coverage": "^3.0.0",
- "source-map": "^0.6.1"
+ "istanbul-lib-coverage": "^3.0.0"
},
"engines": {
"node": ">=10"
}
},
- "node_modules/istanbul-lib-source-maps/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/istanbul-reports": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
"integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"html-escaper": "^2.0.0",
@@ -13524,38 +13172,38 @@
}
},
"node_modules/jackspeak": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
- "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
- "engines": {
- "node": "20 || >=22"
- },
"funding": {
"url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/jest": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
- "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz",
+ "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/core": "^29.7.0",
- "@jest/types": "^29.6.3",
- "import-local": "^3.0.2",
- "jest-cli": "^29.7.0"
+ "@jest/core": "30.3.0",
+ "@jest/types": "30.3.0",
+ "import-local": "^3.2.0",
+ "jest-cli": "30.3.0"
},
"bin": {
"jest": "bin/jest.js"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
"node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
@@ -13567,123 +13215,75 @@
}
},
"node_modules/jest-changed-files": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz",
- "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz",
+ "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "execa": "^5.0.0",
- "jest-util": "^29.7.0",
+ "execa": "^5.1.1",
+ "jest-util": "30.3.0",
"p-limit": "^3.1.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-circus": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz",
- "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz",
+ "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/expect": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
+ "@jest/environment": "30.3.0",
+ "@jest/expect": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "chalk": "^4.0.0",
+ "chalk": "^4.1.2",
"co": "^4.6.0",
- "dedent": "^1.0.0",
- "is-generator-fn": "^2.0.0",
- "jest-each": "^29.7.0",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
+ "dedent": "^1.6.0",
+ "is-generator-fn": "^2.1.0",
+ "jest-each": "30.3.0",
+ "jest-matcher-utils": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-runtime": "30.3.0",
+ "jest-snapshot": "30.3.0",
+ "jest-util": "30.3.0",
"p-limit": "^3.1.0",
- "pretty-format": "^29.7.0",
- "pure-rand": "^6.0.0",
+ "pretty-format": "30.3.0",
+ "pure-rand": "^7.0.0",
"slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-circus/node_modules/jest-diff": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
- "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "diff-sequences": "^29.6.3",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-circus/node_modules/jest-matcher-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
- "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "jest-diff": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-circus/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
+ "stack-utils": "^2.0.6"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-cli": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz",
- "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz",
+ "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/core": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "create-jest": "^29.7.0",
- "exit": "^0.1.2",
- "import-local": "^3.0.2",
- "jest-config": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "yargs": "^17.3.1"
+ "@jest/core": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/types": "30.3.0",
+ "chalk": "^4.1.2",
+ "exit-x": "^0.2.2",
+ "import-local": "^3.2.0",
+ "jest-config": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0",
+ "yargs": "^17.7.2"
},
"bin": {
"jest": "bin/jest.js"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
"node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
@@ -13695,170 +13295,190 @@
}
},
"node_modules/jest-config": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz",
- "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz",
+ "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/test-sequencer": "^29.7.0",
- "@jest/types": "^29.6.3",
- "babel-jest": "^29.7.0",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "deepmerge": "^4.2.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-circus": "^29.7.0",
- "jest-environment-node": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-runner": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "micromatch": "^4.0.4",
+ "@babel/core": "^7.27.4",
+ "@jest/get-type": "30.1.0",
+ "@jest/pattern": "30.0.1",
+ "@jest/test-sequencer": "30.3.0",
+ "@jest/types": "30.3.0",
+ "babel-jest": "30.3.0",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "deepmerge": "^4.3.1",
+ "glob": "^10.5.0",
+ "graceful-fs": "^4.2.11",
+ "jest-circus": "30.3.0",
+ "jest-docblock": "30.2.0",
+ "jest-environment-node": "30.3.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.3.0",
+ "jest-runner": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0",
"parse-json": "^5.2.0",
- "pretty-format": "^29.7.0",
+ "pretty-format": "30.3.0",
"slash": "^3.0.0",
"strip-json-comments": "^3.1.1"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
"@types/node": "*",
+ "esbuild-register": ">=3.4.0",
"ts-node": ">=9.0.0"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
+ "esbuild-register": {
+ "optional": true
+ },
"ts-node": {
"optional": true
}
}
},
- "node_modules/jest-diff": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz",
- "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==",
+ "node_modules/jest-config/node_modules/brace-expansion": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/diff-sequences": "30.0.1",
- "@jest/get-type": "30.1.0",
- "chalk": "^4.1.2",
- "pretty-format": "30.2.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ "balanced-match": "^1.0.0"
}
},
- "node_modules/jest-diff/node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "node_modules/jest-config/node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"dependencies": {
- "@sinclair/typebox": "^0.34.0"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
},
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-diff/node_modules/@sinclair/typebox": {
- "version": "0.34.48",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
- "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
+ "node_modules/jest-config/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
- "license": "MIT"
+ "license": "ISC"
},
- "node_modules/jest-diff/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "node_modules/jest-config/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.2"
+ },
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-diff/node_modules/pretty-format": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
- "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "node_modules/jest-config/node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
- "license": "MIT",
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-diff/node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "node_modules/jest-diff": {
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz",
+ "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "@jest/diff-sequences": "30.3.0",
+ "@jest/get-type": "30.1.0",
+ "chalk": "^4.1.2",
+ "pretty-format": "30.3.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
},
"node_modules/jest-docblock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz",
- "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz",
+ "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "detect-newline": "^3.0.0"
+ "detect-newline": "^3.1.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-each": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz",
- "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz",
+ "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
- "chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
- "jest-util": "^29.7.0",
- "pretty-format": "^29.7.0"
+ "@jest/get-type": "30.1.0",
+ "@jest/types": "30.3.0",
+ "chalk": "^4.1.2",
+ "jest-util": "30.3.0",
+ "pretty-format": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-environment-jsdom": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz",
- "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.3.0.tgz",
+ "integrity": "sha512-RLEOJy6ip1lpw0yqJ8tB3i88FC7VBz7i00Zvl2qF71IdxjS98gC9/0SPWYIBVXHm5hgCYK0PAlSlnHGGy9RoMg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/jsdom": "^20.0.0",
- "@types/node": "*",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0",
- "jsdom": "^20.0.0"
+ "@jest/environment": "30.3.0",
+ "@jest/environment-jsdom-abstract": "30.3.0",
+ "jsdom": "^26.1.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"peerDependencies": {
- "canvas": "^2.5.0"
+ "canvas": "^3.0.0"
},
"peerDependenciesMeta": {
"canvas": {
@@ -13866,50 +13486,23 @@
}
}
},
- "node_modules/jest-environment-jsdom/node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/jest-environment-node": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
- "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/fake-timers": "^29.7.0",
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-mock": "^29.7.0",
- "jest-util": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-environment-node/node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz",
+ "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/environment": "30.3.0",
+ "@jest/fake-timers": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "jest-util": "^29.7.0"
+ "jest-mock": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-fetch-mock": {
@@ -13923,138 +13516,88 @@
"promise-polyfill": "^8.1.3"
}
},
- "node_modules/jest-get-type": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
- "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/jest-haste-map": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
- "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz",
+ "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
- "@types/graceful-fs": "^4.1.3",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "anymatch": "^3.0.3",
- "fb-watchman": "^2.0.0",
- "graceful-fs": "^4.2.9",
- "jest-regex-util": "^29.6.3",
- "jest-util": "^29.7.0",
- "jest-worker": "^29.7.0",
- "micromatch": "^4.0.4",
+ "anymatch": "^3.1.3",
+ "fb-watchman": "^2.0.2",
+ "graceful-fs": "^4.2.11",
+ "jest-regex-util": "30.0.1",
+ "jest-util": "30.3.0",
+ "jest-worker": "30.3.0",
+ "picomatch": "^4.0.3",
"walker": "^1.0.8"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
},
"optionalDependencies": {
- "fsevents": "^2.3.2"
- }
- },
- "node_modules/jest-leak-detector": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
- "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==",
- "license": "MIT",
- "dependencies": {
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "fsevents": "^2.3.3"
}
},
- "node_modules/jest-matcher-utils": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz",
- "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==",
+ "node_modules/jest-haste-map/node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@jest/get-type": "30.1.0",
- "chalk": "^4.1.2",
- "jest-diff": "30.2.0",
- "pretty-format": "30.2.0"
- },
"engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/jest-matcher-utils/node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "node_modules/jest-leak-detector": {
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz",
+ "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@sinclair/typebox": "^0.34.0"
+ "@jest/get-type": "30.1.0",
+ "pretty-format": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-matcher-utils/node_modules/@sinclair/typebox": {
- "version": "0.34.48",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
- "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jest-matcher-utils/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/pretty-format": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
- "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "node_modules/jest-matcher-utils": {
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz",
+ "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
+ "@jest/get-type": "30.1.0",
+ "chalk": "^4.1.2",
+ "jest-diff": "30.3.0",
+ "pretty-format": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-matcher-utils/node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/jest-message-util": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz",
- "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz",
+ "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
- "@jest/types": "30.2.0",
+ "@jest/types": "30.3.0",
"@types/stack-utils": "^2.0.3",
"chalk": "^4.1.2",
"graceful-fs": "^4.2.11",
- "micromatch": "^4.0.8",
- "pretty-format": "30.2.0",
+ "picomatch": "^4.0.3",
+ "pretty-format": "30.3.0",
"slash": "^3.0.0",
"stack-utils": "^2.0.6"
},
@@ -14062,84 +13605,39 @@
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-message-util/node_modules/@jest/schemas": {
- "version": "30.0.5",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
- "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.34.0"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-message-util/node_modules/@jest/types": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
- "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/pattern": "30.0.1",
- "@jest/schemas": "30.0.5",
- "@types/istanbul-lib-coverage": "^2.0.6",
- "@types/istanbul-reports": "^3.0.4",
- "@types/node": "*",
- "@types/yargs": "^17.0.33",
- "chalk": "^4.1.2"
- },
- "engines": {
- "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
- }
- },
- "node_modules/jest-message-util/node_modules/@sinclair/typebox": {
- "version": "0.34.48",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz",
- "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jest-message-util/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "node_modules/jest-message-util/node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=10"
+ "node": ">=12"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/jest-message-util/node_modules/pretty-format": {
- "version": "30.2.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
- "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "node_modules/jest-mock": {
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz",
+ "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jest/schemas": "30.0.5",
- "ansi-styles": "^5.2.0",
- "react-is": "^18.3.1"
+ "@jest/types": "30.3.0",
+ "@types/node": "*",
+ "jest-util": "30.3.0"
},
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-message-util/node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/jest-pnp-resolver": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
"integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -14154,279 +13652,227 @@
}
},
"node_modules/jest-regex-util": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
- "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz",
+ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-resolve": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz",
- "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz",
+ "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-pnp-resolver": "^1.2.2",
- "jest-util": "^29.7.0",
- "jest-validate": "^29.7.0",
- "resolve": "^1.20.0",
- "resolve.exports": "^2.0.0",
- "slash": "^3.0.0"
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.3.0",
+ "jest-pnp-resolver": "^1.2.3",
+ "jest-util": "30.3.0",
+ "jest-validate": "30.3.0",
+ "slash": "^3.0.0",
+ "unrs-resolver": "^1.7.11"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-resolve-dependencies": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz",
- "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz",
+ "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "jest-regex-util": "^29.6.3",
- "jest-snapshot": "^29.7.0"
+ "jest-regex-util": "30.0.1",
+ "jest-snapshot": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-runner": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz",
- "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz",
+ "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/console": "^29.7.0",
- "@jest/environment": "^29.7.0",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
+ "@jest/console": "30.3.0",
+ "@jest/environment": "30.3.0",
+ "@jest/test-result": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "chalk": "^4.0.0",
+ "chalk": "^4.1.2",
"emittery": "^0.13.1",
- "graceful-fs": "^4.2.9",
- "jest-docblock": "^29.7.0",
- "jest-environment-node": "^29.7.0",
- "jest-haste-map": "^29.7.0",
- "jest-leak-detector": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-resolve": "^29.7.0",
- "jest-runtime": "^29.7.0",
- "jest-util": "^29.7.0",
- "jest-watcher": "^29.7.0",
- "jest-worker": "^29.7.0",
+ "exit-x": "^0.2.2",
+ "graceful-fs": "^4.2.11",
+ "jest-docblock": "30.2.0",
+ "jest-environment-node": "30.3.0",
+ "jest-haste-map": "30.3.0",
+ "jest-leak-detector": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-resolve": "30.3.0",
+ "jest-runtime": "30.3.0",
+ "jest-util": "30.3.0",
+ "jest-watcher": "30.3.0",
+ "jest-worker": "30.3.0",
"p-limit": "^3.1.0",
"source-map-support": "0.5.13"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-runner/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
+ "node_modules/jest-runtime": {
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz",
+ "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-runtime": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz",
- "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
- "license": "MIT",
- "dependencies": {
- "@jest/environment": "^29.7.0",
- "@jest/fake-timers": "^29.7.0",
- "@jest/globals": "^29.7.0",
- "@jest/source-map": "^29.6.3",
- "@jest/test-result": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
+ "@jest/environment": "30.3.0",
+ "@jest/fake-timers": "30.3.0",
+ "@jest/globals": "30.3.0",
+ "@jest/source-map": "30.0.1",
+ "@jest/test-result": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "chalk": "^4.0.0",
- "cjs-module-lexer": "^1.0.0",
- "collect-v8-coverage": "^1.0.0",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-mock": "^29.7.0",
- "jest-regex-util": "^29.6.3",
- "jest-resolve": "^29.7.0",
- "jest-snapshot": "^29.7.0",
- "jest-util": "^29.7.0",
+ "chalk": "^4.1.2",
+ "cjs-module-lexer": "^2.1.0",
+ "collect-v8-coverage": "^1.0.2",
+ "glob": "^10.5.0",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-mock": "30.3.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.3.0",
+ "jest-snapshot": "30.3.0",
+ "jest-util": "30.3.0",
"slash": "^3.0.0",
"strip-bom": "^4.0.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/jest-runtime/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
+ "node_modules/jest-runtime/node_modules/brace-expansion": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "balanced-match": "^1.0.0"
}
},
- "node_modules/jest-runtime/node_modules/jest-mock": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
- "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
- "license": "MIT",
+ "node_modules/jest-runtime/node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "jest-util": "^29.7.0"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
},
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-snapshot": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
- "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@babel/generator": "^7.7.2",
- "@babel/plugin-syntax-jsx": "^7.7.2",
- "@babel/plugin-syntax-typescript": "^7.7.2",
- "@babel/types": "^7.3.3",
- "@jest/expect-utils": "^29.7.0",
- "@jest/transform": "^29.7.0",
- "@jest/types": "^29.6.3",
- "babel-preset-current-node-syntax": "^1.0.0",
- "chalk": "^4.0.0",
- "expect": "^29.7.0",
- "graceful-fs": "^4.2.9",
- "jest-diff": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0",
- "natural-compare": "^1.4.0",
- "pretty-format": "^29.7.0",
- "semver": "^7.5.3"
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
},
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-snapshot/node_modules/@jest/expect-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
- "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
- "license": "MIT",
- "dependencies": {
- "jest-get-type": "^29.6.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
+ "node_modules/jest-runtime/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
},
- "node_modules/jest-snapshot/node_modules/expect": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
- "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
- "license": "MIT",
+ "node_modules/jest-runtime/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "@jest/expect-utils": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "jest-matcher-utils": "^29.7.0",
- "jest-message-util": "^29.7.0",
- "jest-util": "^29.7.0"
+ "brace-expansion": "^2.0.2"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-snapshot/node_modules/jest-diff": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
- "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "diff-sequences": "^29.6.3",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
+ "node": ">=16 || 14 >=14.17"
},
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-snapshot/node_modules/jest-matcher-utils": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
- "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
- "license": "MIT",
+ "node_modules/jest-runtime/node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "chalk": "^4.0.0",
- "jest-diff": "^29.7.0",
- "jest-get-type": "^29.6.3",
- "pretty-format": "^29.7.0"
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-snapshot/node_modules/jest-message-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
- "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
+ "node_modules/jest-snapshot": {
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz",
+ "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^29.6.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
+ "@babel/core": "^7.27.4",
+ "@babel/generator": "^7.27.5",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/plugin-syntax-typescript": "^7.27.1",
+ "@babel/types": "^7.27.3",
+ "@jest/expect-utils": "30.3.0",
+ "@jest/get-type": "30.1.0",
+ "@jest/snapshot-utils": "30.3.0",
+ "@jest/transform": "30.3.0",
+ "@jest/types": "30.3.0",
+ "babel-preset-current-node-syntax": "^1.2.0",
+ "chalk": "^4.1.2",
+ "expect": "30.3.0",
+ "graceful-fs": "^4.2.11",
+ "jest-diff": "30.3.0",
+ "jest-matcher-utils": "30.3.0",
+ "jest-message-util": "30.3.0",
+ "jest-util": "30.3.0",
+ "pretty-format": "30.3.0",
+ "semver": "^7.7.2",
+ "synckit": "^0.11.8"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-snapshot/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -14436,77 +13882,96 @@
}
},
"node_modules/jest-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
- "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz",
+ "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "graceful-fs": "^4.2.9",
- "picomatch": "^2.2.3"
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "graceful-fs": "^4.2.11",
+ "picomatch": "^4.0.3"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-util/node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/jest-validate": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
- "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz",
+ "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/types": "^29.6.3",
- "camelcase": "^6.2.0",
- "chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
+ "@jest/get-type": "30.1.0",
+ "@jest/types": "30.3.0",
+ "camelcase": "^6.3.0",
+ "chalk": "^4.1.2",
"leven": "^3.1.0",
- "pretty-format": "^29.7.0"
+ "pretty-format": "30.3.0"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-watcher": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz",
- "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz",
+ "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/test-result": "^29.7.0",
- "@jest/types": "^29.6.3",
+ "@jest/test-result": "30.3.0",
+ "@jest/types": "30.3.0",
"@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
+ "ansi-escapes": "^4.3.2",
+ "chalk": "^4.1.2",
"emittery": "^0.13.1",
- "jest-util": "^29.7.0",
- "string-length": "^4.0.1"
+ "jest-util": "30.3.0",
+ "string-length": "^4.0.2"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-worker": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
- "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz",
+ "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
- "jest-util": "^29.7.0",
+ "@ungap/structured-clone": "^1.3.0",
+ "jest-util": "30.3.0",
"merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
+ "supports-color": "^8.1.1"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/jest-worker/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -14528,6 +13993,7 @@
"version": "3.14.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
@@ -14538,44 +14004,38 @@
}
},
"node_modules/jsdom": {
- "version": "20.0.3",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz",
- "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "abab": "^2.0.6",
- "acorn": "^8.8.1",
- "acorn-globals": "^7.0.0",
- "cssom": "^0.5.0",
- "cssstyle": "^2.3.0",
- "data-urls": "^3.0.2",
- "decimal.js": "^10.4.2",
- "domexception": "^4.0.0",
- "escodegen": "^2.0.0",
- "form-data": "^4.0.0",
- "html-encoding-sniffer": "^3.0.0",
- "http-proxy-agent": "^5.0.0",
- "https-proxy-agent": "^5.0.1",
+ "version": "26.1.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
+ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssstyle": "^4.2.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.5.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.6",
"is-potential-custom-element-name": "^1.0.1",
- "nwsapi": "^2.2.2",
- "parse5": "^7.1.1",
+ "nwsapi": "^2.2.16",
+ "parse5": "^7.2.1",
+ "rrweb-cssom": "^0.8.0",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
- "tough-cookie": "^4.1.2",
- "w3c-xmlserializer": "^4.0.0",
+ "tough-cookie": "^5.1.1",
+ "w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^7.0.0",
- "whatwg-encoding": "^2.0.0",
- "whatwg-mimetype": "^3.0.0",
- "whatwg-url": "^11.0.0",
- "ws": "^8.11.0",
- "xml-name-validator": "^4.0.0"
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.1.1",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=18"
},
"peerDependencies": {
- "canvas": "^2.5.0"
+ "canvas": "^3.0.0"
},
"peerDependenciesMeta": {
"canvas": {
@@ -14655,15 +14115,6 @@
"json-buffer": "3.0.1"
}
},
- "node_modules/kleur": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/language-subtag-registry": {
"version": "0.3.23",
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
@@ -14686,6 +14137,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -14710,40 +14162,6 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"license": "MIT"
},
- "node_modules/lit": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz",
- "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@lit/reactive-element": "^1.6.0",
- "lit-element": "^3.3.0",
- "lit-html": "^2.8.0"
- }
- },
- "node_modules/lit-element": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz",
- "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@lit-labs/ssr-dom-shim": "^1.1.0",
- "@lit/reactive-element": "^1.3.0",
- "lit-html": "^2.8.0"
- }
- },
- "node_modules/lit-html": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz",
- "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@types/trusted-types": "^2.0.2"
- }
- },
"node_modules/loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
@@ -14775,9 +14193,9 @@
}
},
"node_modules/lodash": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
- "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"dev": true,
"license": "MIT"
},
@@ -14862,6 +14280,7 @@
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
"integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"tmpl": "1.0.5"
@@ -14893,6 +14312,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
"license": "MIT"
},
"node_modules/merge2": {
@@ -14917,33 +14337,11 @@
"node": ">=8.6"
}
},
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -14960,9 +14358,9 @@
}
},
"node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -14981,11 +14379,11 @@
}
},
"node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
"dev": true,
- "license": "ISC",
+ "license": "BlueOak-1.0.0",
"engines": {
"node": ">=16 || 14 >=14.17"
}
@@ -15053,14 +14451,14 @@
"license": "MIT"
},
"node_modules/next": {
- "version": "16.1.6",
- "resolved": "https://registry.npmjs.org/next/-/next-16.1.6.tgz",
- "integrity": "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==",
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.2.3.tgz",
+ "integrity": "sha512-9V3zV4oZFza3PVev5/poB9g0dEafVcgNyQ8eTRop8GvxZjV2G15FC5ARuG1eFD42QgeYkzJBJzHghNP8Ad9xtA==",
"license": "MIT",
"dependencies": {
- "@next/env": "16.1.6",
+ "@next/env": "16.2.3",
"@swc/helpers": "0.5.15",
- "baseline-browser-mapping": "^2.8.3",
+ "baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
"postcss": "8.4.31",
"styled-jsx": "5.1.6"
@@ -15072,15 +14470,15 @@
"node": ">=20.9.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "16.1.6",
- "@next/swc-darwin-x64": "16.1.6",
- "@next/swc-linux-arm64-gnu": "16.1.6",
- "@next/swc-linux-arm64-musl": "16.1.6",
- "@next/swc-linux-x64-gnu": "16.1.6",
- "@next/swc-linux-x64-musl": "16.1.6",
- "@next/swc-win32-arm64-msvc": "16.1.6",
- "@next/swc-win32-x64-msvc": "16.1.6",
- "sharp": "^0.34.4"
+ "@next/swc-darwin-arm64": "16.2.3",
+ "@next/swc-darwin-x64": "16.2.3",
+ "@next/swc-linux-arm64-gnu": "16.2.3",
+ "@next/swc-linux-arm64-musl": "16.2.3",
+ "@next/swc-linux-x64-gnu": "16.2.3",
+ "@next/swc-linux-x64-musl": "16.2.3",
+ "@next/swc-win32-arm64-msvc": "16.2.3",
+ "@next/swc-win32-x64-msvc": "16.2.3",
+ "sharp": "^0.34.5"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -15183,6 +14581,7 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
"integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true,
"license": "MIT"
},
"node_modules/node-releases": {
@@ -15195,6 +14594,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -15204,6 +14604,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.0.0"
@@ -15368,6 +14769,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
@@ -15377,6 +14779,7 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"mimic-fn": "^2.1.0"
@@ -15475,6 +14878,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -15552,10 +14956,27 @@
"node": ">=8"
}
},
+ "node_modules/path-expression-matcher": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz",
+ "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -15577,9 +14998,9 @@
"license": "MIT"
},
"node_modules/path-scurry": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz",
- "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
@@ -15587,16 +15008,16 @@
"minipass": "^7.1.2"
},
"engines": {
- "node": "20 || >=22"
+ "node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
- "version": "11.2.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz",
- "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==",
+ "version": "11.3.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz",
+ "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -15629,9 +15050,9 @@
"license": "ISC"
},
"node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -15644,9 +15065,79 @@
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
"integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
"engines": {
- "node": ">= 6"
+ "node": ">=8"
}
},
"node_modules/playwright": {
@@ -15757,23 +15248,25 @@
}
},
"node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+ "version": "30.3.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz",
+ "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
},
"engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/pretty-format/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -15786,6 +15279,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/process-nextick-args": {
@@ -15801,19 +15295,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/prompts": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
- "license": "MIT",
- "dependencies": {
- "kleur": "^3.0.3",
- "sisteransi": "^1.0.5"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -15831,19 +15312,6 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"license": "MIT"
},
- "node_modules/psl": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
- "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/lupomontero"
- }
- },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -15854,9 +15322,10 @@
}
},
"node_modules/pure-rand": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
- "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz",
+ "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==",
+ "dev": true,
"funding": [
{
"type": "individual",
@@ -15869,13 +15338,6 @@
],
"license": "MIT"
},
- "node_modules/querystringify": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
- "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -15905,6 +15367,28 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-docgen": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.3.tgz",
+ "integrity": "sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.28.0",
+ "@babel/traverse": "^7.28.0",
+ "@babel/types": "^7.28.2",
+ "@types/babel__core": "^7.20.5",
+ "@types/babel__traverse": "^7.20.7",
+ "@types/doctrine": "^0.0.9",
+ "@types/resolve": "^1.20.2",
+ "doctrine": "^3.0.0",
+ "resolve": "^1.22.1",
+ "strip-indent": "^4.0.0"
+ },
+ "engines": {
+ "node": "^20.9.0 || >=22"
+ }
+ },
"node_modules/react-docgen-typescript": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz",
@@ -15915,6 +15399,19 @@
"typescript": ">= 4.3.x"
}
},
+ "node_modules/react-docgen/node_modules/strip-indent": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz",
+ "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/react-dom": {
"version": "19.2.4",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
@@ -16158,6 +15655,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -16173,13 +15671,6 @@
"node": ">=0.10.5"
}
},
- "node_modules/requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/resolve": {
"version": "1.22.11",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
@@ -16204,6 +15695,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
"integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"resolve-from": "^5.0.0"
@@ -16216,6 +15708,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -16230,15 +15723,6 @@
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
- "node_modules/resolve.exports": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz",
- "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/reusify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
@@ -16250,9 +15734,9 @@
}
},
"node_modules/rollup": {
- "version": "4.57.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz",
- "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==",
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz",
+ "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -16266,34 +15750,41 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.57.1",
- "@rollup/rollup-android-arm64": "4.57.1",
- "@rollup/rollup-darwin-arm64": "4.57.1",
- "@rollup/rollup-darwin-x64": "4.57.1",
- "@rollup/rollup-freebsd-arm64": "4.57.1",
- "@rollup/rollup-freebsd-x64": "4.57.1",
- "@rollup/rollup-linux-arm-gnueabihf": "4.57.1",
- "@rollup/rollup-linux-arm-musleabihf": "4.57.1",
- "@rollup/rollup-linux-arm64-gnu": "4.57.1",
- "@rollup/rollup-linux-arm64-musl": "4.57.1",
- "@rollup/rollup-linux-loong64-gnu": "4.57.1",
- "@rollup/rollup-linux-loong64-musl": "4.57.1",
- "@rollup/rollup-linux-ppc64-gnu": "4.57.1",
- "@rollup/rollup-linux-ppc64-musl": "4.57.1",
- "@rollup/rollup-linux-riscv64-gnu": "4.57.1",
- "@rollup/rollup-linux-riscv64-musl": "4.57.1",
- "@rollup/rollup-linux-s390x-gnu": "4.57.1",
- "@rollup/rollup-linux-x64-gnu": "4.57.1",
- "@rollup/rollup-linux-x64-musl": "4.57.1",
- "@rollup/rollup-openbsd-x64": "4.57.1",
- "@rollup/rollup-openharmony-arm64": "4.57.1",
- "@rollup/rollup-win32-arm64-msvc": "4.57.1",
- "@rollup/rollup-win32-ia32-msvc": "4.57.1",
- "@rollup/rollup-win32-x64-gnu": "4.57.1",
- "@rollup/rollup-win32-x64-msvc": "4.57.1",
+ "@rollup/rollup-android-arm-eabi": "4.60.1",
+ "@rollup/rollup-android-arm64": "4.60.1",
+ "@rollup/rollup-darwin-arm64": "4.60.1",
+ "@rollup/rollup-darwin-x64": "4.60.1",
+ "@rollup/rollup-freebsd-arm64": "4.60.1",
+ "@rollup/rollup-freebsd-x64": "4.60.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.60.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.60.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.60.1",
+ "@rollup/rollup-linux-arm64-musl": "4.60.1",
+ "@rollup/rollup-linux-loong64-gnu": "4.60.1",
+ "@rollup/rollup-linux-loong64-musl": "4.60.1",
+ "@rollup/rollup-linux-ppc64-gnu": "4.60.1",
+ "@rollup/rollup-linux-ppc64-musl": "4.60.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.60.1",
+ "@rollup/rollup-linux-riscv64-musl": "4.60.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.60.1",
+ "@rollup/rollup-linux-x64-gnu": "4.60.1",
+ "@rollup/rollup-linux-x64-musl": "4.60.1",
+ "@rollup/rollup-openbsd-x64": "4.60.1",
+ "@rollup/rollup-openharmony-arm64": "4.60.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.60.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.60.1",
+ "@rollup/rollup-win32-x64-gnu": "4.60.1",
+ "@rollup/rollup-win32-x64-msvc": "4.60.1",
"fsevents": "~2.3.2"
}
},
+ "node_modules/rrweb-cssom": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/run-applescript": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
@@ -16401,6 +15892,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/sax": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
+ "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=11.0.0"
+ }
+ },
"node_modules/saxes": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
@@ -16649,18 +16150,14 @@
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
"license": "ISC"
},
- "node_modules/sisteransi": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "license": "MIT"
- },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -16688,6 +16185,7 @@
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
@@ -16698,12 +16196,14 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/source-map-support/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -16713,6 +16213,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
"license": "BSD-3-Clause"
},
"node_modules/stable": {
@@ -16733,6 +16234,7 @@
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
"integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"escape-string-regexp": "^2.0.0"
@@ -16745,6 +16247,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -16764,18 +16267,19 @@
}
},
"node_modules/storybook": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.2.2.tgz",
- "integrity": "sha512-6vFtykuCEolgO6pG3sXmhNMsAbe+PKgW4cbfqjJcM1bK89qbWBxad7gUsPs7P8SctPjpssQcOCL15vH/g9lgMQ==",
+ "version": "10.3.5",
+ "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.3.5.tgz",
+ "integrity": "sha512-uBSZu/GZa9aEIW3QMGvdQPMZWhGxSe4dyRWU8B3/Vd47Gy/XLC7tsBxRr13txmmPOEDHZR94uLuq0H50fvuqBw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@storybook/global": "^5.0.0",
"@storybook/icons": "^2.0.1",
- "@testing-library/jest-dom": "^6.6.3",
+ "@testing-library/jest-dom": "^6.9.1",
"@testing-library/user-event": "^14.6.1",
"@vitest/expect": "3.2.4",
"@vitest/spy": "3.2.4",
+ "@webcontainer/env": "^1.1.1",
"esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0",
"open": "^10.2.0",
"recast": "^0.23.5",
@@ -16799,16 +16303,6 @@
}
}
},
- "node_modules/storybook-addon-designs": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/storybook-addon-designs/-/storybook-addon-designs-6.3.1.tgz",
- "integrity": "sha512-QCHZp4KuUikOq52MPiMfU8QifYTfhHar5vWlbcfkFDz1YrgGMy+QAEt5Y3Vdnffl4GKSK1lAsLuvTuzqTBRvnw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@figspec/react": "^1.0.0"
- }
- },
"node_modules/storybook/node_modules/@testing-library/jest-dom": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz",
@@ -16937,6 +16431,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
"integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"char-regex": "^1.0.2",
@@ -16950,6 +16445,7 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -16987,6 +16483,7 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
"license": "MIT"
},
"node_modules/string.prototype.includes": {
@@ -17100,6 +16597,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -17126,6 +16624,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -17135,6 +16634,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -17166,9 +16666,9 @@
}
},
"node_modules/strnum": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz",
- "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz",
+ "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==",
"dev": true,
"funding": [
{
@@ -17252,18 +16752,18 @@
"license": "MIT"
},
"node_modules/svgo": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
- "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.2.tgz",
+ "integrity": "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@trysound/sax": "0.2.0",
"commander": "^7.2.0",
"css-select": "^4.1.3",
"css-tree": "^1.1.3",
"csso": "^4.2.0",
"picocolors": "^1.0.0",
+ "sax": "^1.5.0",
"stable": "^0.1.8"
},
"bin": {
@@ -17290,10 +16790,27 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/synckit": {
+ "version": "0.11.12",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz",
+ "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.2.9"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
"node_modules/test-exclude": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
"integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"@istanbuljs/schema": "^0.1.2",
@@ -17304,6 +16821,28 @@
"node": ">=8"
}
},
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -17344,9 +16883,9 @@
}
},
"node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -17355,10 +16894,31 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true,
"license": "BSD-3-Clause"
},
"node_modules/to-regex-range": {
@@ -17374,42 +16934,29 @@
}
},
"node_modules/tough-cookie": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
- "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
- "psl": "^1.1.33",
- "punycode": "^2.1.1",
- "universalify": "^0.2.0",
- "url-parse": "^1.5.3"
+ "tldts": "^6.1.32"
},
"engines": {
- "node": ">=6"
- }
- },
- "node_modules/tough-cookie/node_modules/universalify": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4.0.0"
+ "node": ">=16"
}
},
"node_modules/tr46": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
- "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "punycode": "^2.1.1"
+ "punycode": "^2.3.1"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/ts-api-utils": {
@@ -17527,11 +17074,25 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
}
},
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/typed-array-buffer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
@@ -17607,9 +17168,9 @@
}
},
"node_modules/typescript": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
- "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -17741,21 +17302,21 @@
}
},
"node_modules/typescript-eslint/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/typescript-eslint/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"license": "ISC",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -17855,9 +17416,9 @@
}
},
"node_modules/unplugin/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -17940,17 +17501,6 @@
"punycode": "^2.1.0"
}
},
- "node_modules/url-parse": {
- "version": "1.5.10",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
- "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "querystringify": "^2.1.1",
- "requires-port": "^1.0.0"
- }
- },
"node_modules/use-sync-external-store": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
@@ -17984,6 +17534,7 @@
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
"integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.12",
@@ -17995,9 +17546,9 @@
}
},
"node_modules/vite": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
- "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz",
+ "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -18130,9 +17681,9 @@
}
},
"node_modules/vite/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -18143,22 +17694,23 @@
}
},
"node_modules/w3c-xmlserializer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
- "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "xml-name-validator": "^4.0.0"
+ "xml-name-validator": "^5.0.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=18"
}
},
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
"integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
"license": "Apache-2.0",
"dependencies": {
"makeerror": "1.0.12"
@@ -18182,9 +17734,9 @@
"license": "MIT"
},
"node_modules/whatwg-encoding": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
- "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
"dev": true,
"license": "MIT",
@@ -18192,44 +17744,31 @@
"iconv-lite": "0.6.3"
},
"engines": {
- "node": ">=12"
- }
- },
- "node_modules/whatwg-encoding/node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
+ "node": ">=18"
}
},
"node_modules/whatwg-mimetype": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
- "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/whatwg-url": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
- "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "tr46": "^3.0.0",
+ "tr46": "^5.1.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/which": {
@@ -18351,6 +17890,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@@ -18387,19 +17927,34 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/write-file-atomic": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
- "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
+ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.7"
+ "signal-exit": "^4.0.1"
},
"engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/write-file-atomic/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ws": {
@@ -18441,13 +17996,13 @@
}
},
"node_modules/xml-name-validator": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
- "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
"dev": true,
"license": "Apache-2.0",
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/xmlchars": {
@@ -18478,6 +18033,7 @@
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
"license": "ISC",
"engines": {
"node": ">=10"
@@ -18490,9 +18046,9 @@
"license": "ISC"
},
"node_modules/yaml": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
- "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz",
+ "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
"license": "ISC",
"engines": {
"node": ">= 6"
@@ -18502,6 +18058,7 @@
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"cliui": "^8.0.1",
@@ -18520,6 +18077,7 @@
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
"license": "ISC",
"engines": {
"node": ">=12"
diff --git a/frontend/package.json b/frontend/package.json
index fb06132d..223af0d8 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -25,10 +25,9 @@
"@types/react-dom": "^19.0.0",
"dedent": "^1.5.1",
"eslint": "^9.0.0",
- "eslint-config-next": "^16.0.0",
- "jest-cli": "^29.6.4",
+ "eslint-config-next": "^16.2.3",
"memory-cache": "^0.2.0",
- "next": "^16.0.0",
+ "next": "^16.2.3",
"playwright": "^1.37.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
@@ -40,11 +39,11 @@
"@aws-sdk/client-secrets-manager": "^3.978.0",
"@babel/core": "^7.26.10",
"@playwright/test": "^1.51.0",
- "@storybook/addon-a11y": "^10.2.2",
- "@storybook/addon-docs": "^10.2.2",
- "@storybook/addon-links": "^10.2.2",
- "@storybook/nextjs-vite": "10.2.2",
- "@storybook/react": "^10.2.2",
+ "@storybook/addon-a11y": "^10.2.10",
+ "@storybook/addon-docs": "^10.2.10",
+ "@storybook/addon-links": "^10.2.10",
+ "@storybook/nextjs-vite": "10.2.10",
+ "@storybook/react": "^10.2.10",
"@svgr/webpack": "^6.5.1",
"@tanstack/react-query-devtools": "^4.33.0",
"@testing-library/jest-dom": "^5.16.5",
@@ -57,18 +56,18 @@
"dotenv": "^16.4.7",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-jest-dom": "^5.0.0",
- "eslint-plugin-storybook": "^10.2.2",
+ "eslint-plugin-storybook": "^10.2.10",
"eslint-plugin-testing-library": "^6.0.0",
- "jest": "^29.6.4",
- "jest-environment-jsdom": "^29.3.1",
+ "jest": "^30.2.0",
+ "jest-cli": "^30.2.0",
+ "jest-environment-jsdom": "^30.2.0",
"jest-fetch-mock": "^3.0.3",
"prettier": "^2.8.1",
- "pretty-format": "^29.3.1",
- "storybook": "^10.2.2",
- "storybook-addon-designs": "^6.3.1",
- "typescript": "5.1.6",
+ "pretty-format": "^30.2.0",
+ "storybook": "^10.2.10",
+ "typescript": "^5.4.0",
"uuid": "^13.0.0",
- "vite": "^7.0.0"
+ "vite": "^7.3.2"
},
"overrides": {
"copy-anything": "4.0.4"
diff --git a/frontend/playwright.config.ts b/frontend/playwright.config.ts
index 4f31eb49..2d49f5d6 100644
--- a/frontend/playwright.config.ts
+++ b/frontend/playwright.config.ts
@@ -13,7 +13,9 @@ export default defineConfig({
use: {
...devices['Desktop Chrome'],
// Use prepared auth state.
- storageState: 'playwright/.auth/user.json'
+ storageState: 'playwright/.auth/user.json',
+ trace: 'retain-on-failure',
+ screenshot: 'only-on-failure'
},
dependencies: ['setup']
}
diff --git a/frontend/playwright/test-data-flow.spec.ts b/frontend/playwright/test-data-flow.spec.ts
index 09acaa10..47d391f2 100644
--- a/frontend/playwright/test-data-flow.spec.ts
+++ b/frontend/playwright/test-data-flow.spec.ts
@@ -12,7 +12,7 @@ test('test', async ({ page }) => {
await page.goto(domain)
// Create a schema
- await page.locator('div[role="button"]:has-text("Create Schema")').click()
+ await page.getByRole('link', { name: 'Add New Dataset' }).click()
await expect(page).toHaveURL(`${domain}/schema/create`)
await page.locator('[data-testid="field-level"]').selectOption('PUBLIC')
await page.locator('[data-testid="field-layer"]').selectOption('default')
@@ -20,35 +20,33 @@ test('test', async ({ page }) => {
await page.locator('[data-testid="field-domain"]').fill('ui_test_domain')
await page.locator('[data-testid="field-title"]').click()
await page.locator('[data-testid="field-title"]').fill(datasetName)
- await page.locator('[data-testid="field-file"]').click()
await page.locator('[data-testid="field-file"]').setInputFiles(filePath)
await page.locator('[data-testid="submit"]').click()
await page.locator('input[name="ownerEmail"]').click()
await page.locator('input[name="ownerEmail"]').fill('ui_test@email.com')
await page.locator('input[name="ownerName"]').click()
await page.locator('input[name="ownerName"]').fill('ui_test')
- await page.locator('button:has-text("Create Schema")').click()
+ await page.locator('button:has-text("Add Dataset")').click()
const schemaCreatedElement = await page.waitForSelector('.MuiAlertTitle-root')
- expect(await schemaCreatedElement.innerText()).toEqual('Schema Created')
+ expect(await schemaCreatedElement.innerText()).toEqual('Dataset added successfully')
// Upload a dataset
- await page.getByRole('button', { name: 'Upload data' }).click()
+ await page.goto(`${domain}/data/upload`)
await page.getByTestId('select-layer').getByRole('combobox').click()
await page.getByRole('option', { name: 'default' }).click()
await page.getByTestId('select-domain').getByRole('combobox').click()
await page.getByRole('option', { name: 'ui_test_domain' }).click()
await page.getByTestId('select-dataset').getByRole('combobox').click()
await page.getByRole('option', { name: datasetName }).click()
- await page.getByTestId('upload').click()
await page.getByTestId('upload').setInputFiles(filePath)
await page.getByTestId('submit').click()
- expect(await page.getByText('Data uploaded successfully').textContent()).toEqual(
- 'Status: Data uploaded successfully'
- )
+ // Upload now redirects to the job detail page once processing completes
+ await page.waitForURL(`${domain}/tasks/*`, { timeout: 30000 })
+ expect(await page.getByText('Success').textContent()).toContain('Success')
// Download the dataset
- await page.getByRole('button', { name: 'Download data' }).click()
+ await page.goto(`${domain}/data/download`)
await page.getByTestId('select-layer').getByRole('combobox').click()
await page.getByRole('option', { name: 'default' }).click()
await page.getByTestId('select-domain').getByRole('combobox').click()
@@ -58,11 +56,10 @@ test('test', async ({ page }) => {
await page.getByTestId('submit').click()
const metadataTable = page.getByRole('table').first()
- expect(await metadataTable.innerText()).toContain('Last uploaded by')
- const lastUploadedByValue = await page.getByRole('row', { name: /Last uploaded by/ }).locator('td').last().innerText()
+ expect((await metadataTable.innerText()).toLowerCase()).toContain('last uploaded by')
+ const lastUploadedByValue = await page.getByRole('row', { name: /Last uploaded by/i }).locator('td').last().innerText()
expect(lastUploadedByValue).not.toEqual('')
- await page.locator('div').filter({ hasText: 'Row Limit' }).locator('div').nth(1).click()
await page.getByPlaceholder('30').fill('200')
const downloadPromise = page.waitForEvent('download')
await page.getByRole('button', { name: 'Download', exact: true }).click()
@@ -76,16 +73,15 @@ test('test', async ({ page }) => {
})
// Search for dataset
- await page.getByRole('button', { name: 'Search Catalog' }).click()
- await page.getByPlaceholder('Catalog Search Term').click()
- await page.getByPlaceholder('Catalog Search Term').fill(datasetName)
- await page.getByPlaceholder('Catalog Search Term').press('Enter')
+ await page.getByRole('link', { name: 'Catalog' }).click()
+ await expect(page).toHaveURL(`${domain}/catalog`)
+ await page.getByPlaceholder('Search by dataset name…').click()
+ await page.getByPlaceholder('Search by dataset name…').fill(datasetName)
expect(await page.getByRole('table').innerText()).toContain(datasetName)
// Delete the dataset
- await page.getByRole('button', { name: 'Delete data' }).click()
- await page.locator('div[role="button"]:has-text("Delete data")').click()
+ await page.goto(`${domain}/data/delete`)
await page.getByTestId('select-layer').getByRole('combobox').click()
await page.getByRole('option', { name: 'default' }).click()
await page.getByTestId('select-domain').getByRole('combobox').click()
diff --git a/frontend/playwright/test-homepage.spec.ts b/frontend/playwright/test-homepage.spec.ts
index edfa8c8a..74018340 100644
--- a/frontend/playwright/test-homepage.spec.ts
+++ b/frontend/playwright/test-homepage.spec.ts
@@ -1,19 +1,23 @@
/* eslint-disable testing-library/prefer-screen-queries */
-import { test } from '@playwright/test'
+import { test, expect } from '@playwright/test'
import { domain } from './utils'
test('test', async ({ page }) => {
await page.goto(domain)
- await page.getByRole('button', { name: 'Create User' }).click()
- await page.getByRole('button', { name: 'Modify User' }).click()
- await page.getByRole('button', { name: 'Download data' }).click()
- await page.getByRole('button', { name: 'Upload data' }).click()
- await page.getByRole('button', { name: 'Create Schema' }).click()
- await page.getByRole('button', { name: 'Task Status' }).click()
- await page.getByRole('link', { name: 'Home' }).click()
- await page.getByRole('link', { name: 'Create User' }).nth(1).click()
- await page.getByRole('link', { name: 'Home' }).click()
- await page.getByRole('button', { name: 'account of current user' }).click()
- await page.getByText('Logout').click()
+
+ await page.getByRole('link', { name: 'Catalog' }).click()
+ await expect(page).toHaveURL(`${domain}/catalog`)
+
+ await page.getByRole('link', { name: 'Add New Dataset' }).click()
+ await expect(page).toHaveURL(`${domain}/schema/create`)
+
+ await page.getByRole('link', { name: 'Jobs' }).click()
+ await expect(page).toHaveURL(`${domain}/tasks`)
+
+ await page.getByRole('link', { name: 'User Admin' }).click()
+ await expect(page).toHaveURL(`${domain}/subject`)
+
+ await page.locator('.MuiAvatar-root').click()
+ await page.getByRole('menuitem', { name: 'Sign out' }).click()
})
diff --git a/frontend/playwright/test-user-flow.spec.ts b/frontend/playwright/test-user-flow.spec.ts
index 55e1343c..1c2cb373 100644
--- a/frontend/playwright/test-user-flow.spec.ts
+++ b/frontend/playwright/test-user-flow.spec.ts
@@ -1,60 +1,24 @@
/* eslint-disable testing-library/prefer-screen-queries */
import { test, expect } from '@playwright/test'
-import { makeAPIRequest, generateRapidAuthToken, domain } from './utils'
+import { domain } from './utils'
const user = `${process.env.E2E_RESOURCE_PREFIX}_ui_test_user`
-test('test', { timeout: 60000 }, async ({ page }) => {
- await page.goto(domain)
+// Read-only walk through the User Admin area. Mutating permissions is covered by
+// the subject unit tests; here we only verify the real-backend navigation:
+// User Admin table -> search -> open a subject -> its permissions render.
+test('test', async ({ page }) => {
+ await page.goto(`${domain}/subject`)
+ await expect(page).toHaveURL(`${domain}/subject`)
- // Modify user to have data admin permissions
- await page.locator('div[role="button"]:has-text("Modify User")').click()
- await expect(page).toHaveURL(`${domain}/subject/modify`)
- await page.locator('[data-testid="field-user"]').selectOption({ label: user })
- await page.locator('[data-testid="submit-button"]').click()
- await page.getByRole('row', { name: 'DATA_ADMIN' }).getByRole('button').click()
- await page.getByTestId('select-type').selectOption('DATA_ADMIN')
- await page
- .getByRole('row')
- .filter({ hasText: 'DATA_ADMIN' })
- .getByRole('button')
- .click()
- await page.getByTestId('submit').click()
- // await expect(page).toHaveURL(/success/)
+ await page.getByPlaceholder('Search by name…').fill(user)
- // Test unique condition where we correctly display permissions when modifying a user
- // even though they might have conflicting permissions within the filtering logic
- const { access_token } = await generateRapidAuthToken()
- const url = page.url()
- let subjectId = url.split('/').pop()
- subjectId = subjectId.split('?')[0]
- await makeAPIRequest(
- 'subjects/permissions',
- 'PUT',
- {
- subject_id: subjectId,
- permissions: [
- 'DATA_ADMIN',
- 'READ_ALL',
- 'USER_ADMIN',
- 'WRITE_ALL',
- 'READ_DEFAULT_PROTECTED_TEST_E2E_PROTECTED'
- ]
- },
- `Bearer ${access_token}`
- )
- await page.locator('div[role="button"]:has-text("Modify User")').click()
- await expect(page).toHaveURL(`${domain}/subject/modify`)
- await page.locator('[data-testid="field-user"]').selectOption({ label: user })
- await page.locator('[data-testid="submit-button"]').click()
- await page
- .getByRole('row', { name: 'READ DEFAULT PROTECTED TEST_E2E_PROTECTED' })
- .getByRole('button')
- .waitFor({ timeout: 30000 })
- await page
- .getByRole('row', { name: 'READ DEFAULT PROTECTED TEST_E2E_PROTECTED' })
- .getByRole('button')
- .click()
- await page.getByTestId('submit').click()
+ const row = page.getByRole('row').filter({ hasText: user }).first()
+ await expect(row).toBeVisible()
+ await row.click()
+
+ await page.waitForURL(`${domain}/subject/modify/*`)
+ await expect(page.getByText(`Edit permissions — ${user}`)).toBeVisible()
+ await expect(page.getByRole('columnheader', { name: 'Type' })).toBeVisible()
})
diff --git a/frontend/src/__tests__/data/delete.test.tsx b/frontend/src/__tests__/data/delete.test.tsx
index 16e59e09..e17f4f77 100644
--- a/frontend/src/__tests__/data/delete.test.tsx
+++ b/frontend/src/__tests__/data/delete.test.tsx
@@ -1,4 +1,4 @@
-import { screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react'
+import { screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import fetchMock from 'jest-fetch-mock'
import DeletePage from '@/pages/data/delete'
@@ -20,10 +20,7 @@ describe('Page: Delete page', () => {
fetchMock.mockResponseOnce(JSON.stringify(mockDataSetsList), { status: 200 })
renderWithProviders( )
- await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
-
- const datasetDropdown = screen.getByTestId('select-dataset')
- expect(datasetDropdown).toBeVisible()
+ await screen.findByTestId('select-dataset')
expect(screen.getByTestId('submit')).toBeInTheDocument()
})
@@ -32,7 +29,6 @@ describe('Page: Delete page', () => {
fetchMock.mockReject(new Error('fake error message'))
renderWithProviders( )
- await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
await waitFor(async () => {
expect(screen.getByText('fake error message')).toBeInTheDocument()
})
@@ -43,7 +39,7 @@ describe('Page: Delete page', () => {
fetchMock.mockResponseOnce(JSON.stringify(mockDataSetsList), { status: 200 })
renderWithProviders( )
- await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
+ await screen.findByTestId('submit')
await userEvent.click(screen.getByTestId('submit'))
@@ -67,7 +63,7 @@ describe('Page: Delete page', () => {
[JSON.stringify(mockSuccess), { status: 200 }]
)
renderWithProviders( )
- await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
+ await screen.findByTestId('select-dataset')
selectAutocompleteOption('select-layer', 'layer')
selectAutocompleteOption('select-domain', 'Pizza')
@@ -88,11 +84,9 @@ describe('Page: Delete page', () => {
fetchMock.mockResponseOnce(JSON.stringify(mockDataSetsList), { status: 200 })
renderWithProviders( )
- await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
-
fetchMock.mockReject(new Error('fake error message'))
- await userEvent.click(screen.getByTestId('submit'))
+ await userEvent.click(await screen.findByTestId('submit'))
await waitFor(async () => {
expect(screen.getByText('fake error message')).toBeInTheDocument()
diff --git a/frontend/src/__tests__/data/upload.test.tsx b/frontend/src/__tests__/data/upload.test.tsx
index 2e0f39ec..0a0fac17 100644
--- a/frontend/src/__tests__/data/upload.test.tsx
+++ b/frontend/src/__tests__/data/upload.test.tsx
@@ -84,7 +84,7 @@ describe('Page: Upload page', () => {
})
})
- it('upload status failure', async () => {
+ it('upload status failure redirects to job page', async () => {
const mockSuccess: UploadDatasetResponse = {
details: {
dataset_version: 12314,
@@ -109,21 +109,12 @@ describe('Page: Upload page', () => {
await userEvent.click(screen.getByTestId('submit'))
- await waitFor(async () => {
- expect(screen.getByTestId('upload-status')).toBeInTheDocument()
- })
-
- await waitFor(async () => {
- const trackLink = screen.getByText('See error details')
- expect(trackLink).toHaveAttribute('href', '/tasks/abc123')
- })
-
- await waitFor(async () => {
- expect(screen.getByText('Status: Data upload error')).toBeInTheDocument()
+ await waitFor(() => {
+ expect(pushSpy).toHaveBeenCalledWith('/tasks/abc123')
})
})
- it('upload status success', async () => {
+ it('upload status success redirects to job page', async () => {
const mockSuccess: UploadDatasetResponse = {
details: {
dataset_version: 12314,
@@ -148,21 +139,12 @@ describe('Page: Upload page', () => {
await userEvent.click(screen.getByTestId('submit'))
- await waitFor(async () => {
- expect(screen.getByTestId('upload-status')).toBeInTheDocument()
- })
-
- await waitFor(async () => {
- const trackLink = screen.getByText('See upload details')
- expect(trackLink).toHaveAttribute('href', '/tasks/abc123')
- })
-
- await waitFor(async () => {
- expect(screen.getByText('Status: Data uploaded successfully')).toBeInTheDocument()
+ await waitFor(() => {
+ expect(pushSpy).toHaveBeenCalledWith('/tasks/abc123')
})
})
- it('upload status in progress', async () => {
+ it('upload status in progress shows processing', async () => {
const mockSuccess: UploadDatasetResponse = {
details: {
dataset_version: 12314,
@@ -187,17 +169,12 @@ describe('Page: Upload page', () => {
await userEvent.click(screen.getByTestId('submit'))
- await waitFor(async () => {
+ await waitFor(() => {
expect(screen.getByTestId('upload-status')).toBeInTheDocument()
})
- const trackLink = screen.getByText('See progress details')
-
- expect(trackLink).toBeInTheDocument()
- expect(trackLink).toHaveAttribute('href', '/tasks/abc123')
- await waitFor(async () => {
- expect(screen.getByText('Status: Data processing')).toBeInTheDocument()
- })
+ expect(screen.getByText(/Processing/)).toBeInTheDocument()
+ expect(pushSpy).not.toHaveBeenCalledWith('/tasks/abc123')
})
it('api error upload', async () => {
diff --git a/frontend/src/__tests__/index.test.tsx b/frontend/src/__tests__/index.test.tsx
index cef5b8b6..6c851d3c 100644
--- a/frontend/src/__tests__/index.test.tsx
+++ b/frontend/src/__tests__/index.test.tsx
@@ -38,7 +38,6 @@ describe('Page: Index page', () => {
expect(screen.queryByTestId('user-management')).not.toBeInTheDocument()
expect(screen.queryByTestId('data-management')).not.toBeInTheDocument()
expect(screen.queryByTestId('schema-management')).not.toBeInTheDocument()
- expect(screen.queryByTestId('task-status')).not.toBeInTheDocument()
})
it('User Management', async () => {
@@ -51,7 +50,6 @@ describe('Page: Index page', () => {
expect(screen.queryByTestId('data-management')).not.toBeInTheDocument()
expect(screen.queryByTestId('schema-management')).not.toBeInTheDocument()
- expect(screen.queryByTestId('task-status')).not.toBeInTheDocument()
})
it('Data Management', async () => {
@@ -61,7 +59,6 @@ describe('Page: Index page', () => {
await waitFor(async () =>
expect(screen.getByTestId('data-management')).toBeVisible()
)
- expect(screen.getByTestId('task-status')).toBeInTheDocument()
expect(screen.queryByTestId('user-management')).not.toBeInTheDocument()
expect(screen.queryByTestId('schema-management')).not.toBeInTheDocument()
})
@@ -73,7 +70,6 @@ describe('Page: Index page', () => {
await waitFor(async () =>
expect(screen.getByTestId('data-management')).toBeVisible()
)
- expect(screen.getByTestId('task-status')).toBeInTheDocument()
expect(screen.queryByTestId('user-management')).not.toBeInTheDocument()
expect(screen.queryByTestId('schema-management')).not.toBeInTheDocument()
})
@@ -88,8 +84,6 @@ describe('Page: Index page', () => {
expect(screen.getByTestId('data-management')).toBeVisible()
)
expect(screen.getByTestId('schema-management')).toBeVisible()
- expect(screen.getByTestId('task-status')).toBeInTheDocument()
-
expect(screen.queryByTestId('user-management')).not.toBeInTheDocument()
})
})
diff --git a/frontend/src/__tests__/subject/index.test.tsx b/frontend/src/__tests__/subject/index.test.tsx
new file mode 100644
index 00000000..086f920f
--- /dev/null
+++ b/frontend/src/__tests__/subject/index.test.tsx
@@ -0,0 +1,110 @@
+import React from 'react'
+import {
+ screen,
+ waitForElementToBeRemoved
+} from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+import fetchMock from 'jest-fetch-mock'
+import SubjectIndex from '@/pages/subject/index'
+import { renderWithProviders } from '@/utils/testing'
+
+const mockPush = jest.fn()
+
+jest.mock('next/router', () => ({
+ useRouter: () => ({ push: mockPush, query: {} })
+}))
+
+const subjects = [
+ { subject_id: 'u1', subject_name: 'Alice', type: 'USER' },
+ { subject_id: 'u2', subject_name: 'Bob', type: 'USER' },
+ { subject_id: 'c1', subject_name: 'ClientOne', type: 'CLIENT' }
+]
+
+const permissions: Record>> = {
+ u1: [{ id: 'USER_ADMIN', type: 'USER_ADMIN' }],
+ u2: [{ id: 'READ_ALL', type: 'READ', layer: 'ALL', sensitivity: 'ALL' }],
+ c1: [{ id: 'WRITE_ALL', type: 'WRITE', layer: 'ALL', sensitivity: 'ALL' }]
+}
+
+function mockInitial() {
+ fetchMock.mockResponse((req) => {
+ if (req.url.endsWith('/api/subjects')) {
+ return Promise.resolve(JSON.stringify(subjects))
+ }
+ const match = req.url.match(/\/api\/permissions\/(.+)$/)
+ if (match) {
+ return Promise.resolve(JSON.stringify(permissions[match[1]] ?? []))
+ }
+ return Promise.resolve('[]')
+ })
+}
+
+describe('Subject index page', () => {
+ afterEach(() => {
+ fetchMock.resetMocks()
+ jest.clearAllMocks()
+ })
+
+ it('renders all subjects with derived roles', async () => {
+ mockInitial()
+ renderWithProviders( )
+
+ await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
+
+ expect(screen.getByText('Alice')).toBeInTheDocument()
+ expect(screen.getByText('Bob')).toBeInTheDocument()
+ expect(screen.getByText('ClientOne')).toBeInTheDocument()
+
+ await screen.findByText('User Admin', {}, { timeout: 3000 })
+ expect(await screen.findByText('Read Only')).toBeInTheDocument()
+ expect(await screen.findByText('Read/Write')).toBeInTheDocument()
+ })
+
+ it('filters by type', async () => {
+ mockInitial()
+ renderWithProviders( )
+
+ await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
+
+ await userEvent.click(screen.getByRole('button', { name: 'Clients' }))
+
+ expect(screen.queryByText('Alice')).not.toBeInTheDocument()
+ expect(screen.queryByText('Bob')).not.toBeInTheDocument()
+ expect(screen.getByText('ClientOne')).toBeInTheDocument()
+ })
+
+ it('filters by search', async () => {
+ mockInitial()
+ renderWithProviders( )
+
+ await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
+
+ await userEvent.type(screen.getByPlaceholderText(/Search by name/i), 'Alice')
+
+ expect(screen.getByText('Alice')).toBeInTheDocument()
+ expect(screen.queryByText('Bob')).not.toBeInTheDocument()
+ expect(screen.queryByText('ClientOne')).not.toBeInTheDocument()
+ })
+
+ it('navigates to modify page on row click', async () => {
+ mockInitial()
+ renderWithProviders( )
+
+ await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
+
+ await userEvent.click(screen.getByText('Alice'))
+
+ expect(mockPush).toHaveBeenCalledWith({
+ pathname: '/subject/modify/u1',
+ query: { name: 'Alice', type: 'USER' }
+ })
+ })
+
+ it('handles error on fetch', async () => {
+ fetchMock.mockReject(new Error('boom'))
+ renderWithProviders( )
+
+ await waitForElementToBeRemoved(() => screen.queryByRole('progressbar'))
+ expect(screen.getByText('boom')).toBeInTheDocument()
+ })
+})
diff --git a/frontend/src/__tests__/tasks.test.tsx b/frontend/src/__tests__/tasks.test.tsx
index 5c5ecad9..f3086ce8 100644
--- a/frontend/src/__tests__/tasks.test.tsx
+++ b/frontend/src/__tests__/tasks.test.tsx
@@ -46,11 +46,7 @@ describe('Page: Login page', () => {
expect(screen.getByText(job.step as string)).toBeVisible()
expect(link).toBeVisible()
- expect(link).toHaveAttribute('href', `tasks/${job.job_id}`)
+ expect(link).toHaveAttribute('href', `/tasks/${job.job_id}`)
})
- // screen.debug()
-
- expect(screen.getByText('Failure Details')).toBeVisible()
- expect(screen.getByText('Failure Details')).toHaveAttribute('href', `tasks/job_id_2`)
})
})
diff --git a/frontend/src/components/CenteredGradientPage/CenteredGradientPage.tsx b/frontend/src/components/CenteredGradientPage/CenteredGradientPage.tsx
new file mode 100644
index 00000000..c5f1541d
--- /dev/null
+++ b/frontend/src/components/CenteredGradientPage/CenteredGradientPage.tsx
@@ -0,0 +1,27 @@
+import { Box, Paper } from '@mui/material'
+import { ReactNode } from 'react'
+
+const CenteredGradientPage = ({
+ children,
+ width = 360
+}: {
+ children: ReactNode
+ width?: number
+}) => {
+ return (
+
+ {children}
+
+ )
+}
+
+export default CenteredGradientPage
diff --git a/frontend/src/components/Chip/LayerChip.tsx b/frontend/src/components/Chip/LayerChip.tsx
new file mode 100644
index 00000000..3fef4b3e
--- /dev/null
+++ b/frontend/src/components/Chip/LayerChip.tsx
@@ -0,0 +1,18 @@
+import { Chip } from '@mui/material'
+
+type LayerColor = 'info' | 'success' | 'warning' | 'default'
+
+function layerColor(layer: string): LayerColor {
+ switch (layer?.toLowerCase()) {
+ case 'raw': return 'info'
+ case 'curated': return 'success'
+ case 'processed': return 'warning'
+ default: return 'default'
+ }
+}
+
+const LayerChip = ({ layer }: { layer: string }) => (
+
+)
+
+export default LayerChip
diff --git a/frontend/src/components/Chip/StatusChip.tsx b/frontend/src/components/Chip/StatusChip.tsx
new file mode 100644
index 00000000..99bb1acd
--- /dev/null
+++ b/frontend/src/components/Chip/StatusChip.tsx
@@ -0,0 +1,18 @@
+import { Chip } from '@mui/material'
+
+const STATUS_PROPS: Record = {
+ SUCCESS: { label: 'Success', color: 'success' },
+ 'IN PROGRESS': { label: 'In Progress', color: 'warning' },
+ FAILED: { label: 'Failed', color: 'error' }
+}
+
+const StatusChip = ({ status }: { status: string }) => {
+ const props = STATUS_PROPS[status]
+ return props ? (
+
+ ) : (
+
+ )
+}
+
+export default StatusChip
diff --git a/frontend/src/components/DatasetSearchBar/DatasetSearchBar.tsx b/frontend/src/components/DatasetSearchBar/DatasetSearchBar.tsx
new file mode 100644
index 00000000..1552c445
--- /dev/null
+++ b/frontend/src/components/DatasetSearchBar/DatasetSearchBar.tsx
@@ -0,0 +1,173 @@
+import { Dataset } from '@/service/types'
+import { useRouter } from 'next/router'
+import { useState, useMemo, useRef, useEffect } from 'react'
+import {
+ Box,
+ Paper,
+ Typography,
+ Button,
+ Chip,
+ TextField,
+ InputAdornment,
+ ClickAwayListener
+} from '@mui/material'
+import SearchIcon from '@mui/icons-material/Search'
+
+const MAX_SUGGESTIONS = 8
+
+const DatasetSearchBar = ({ datasets }: { datasets: Dataset[] }) => {
+ const router = useRouter()
+ const [search, setSearch] = useState('')
+ const [layerFilter, setLayerFilter] = useState('All')
+ const [open, setOpen] = useState(false)
+ const wrapRef = useRef(null)
+
+ const layers = useMemo(() => {
+ const unique = Array.from(new Set(datasets.map((d) => d.layer).filter(Boolean))).sort()
+ return ['All', ...unique]
+ }, [datasets])
+
+ const filtered = useMemo(() => {
+ return datasets.filter((d) => {
+ if (layerFilter !== 'All' && d.layer?.toLowerCase() !== layerFilter.toLowerCase()) return false
+ if (search.trim()) {
+ const q = search.trim().toLowerCase()
+ const haystack = `${d.layer} ${d.domain} ${d.dataset}`.toLowerCase()
+ if (!haystack.includes(q)) return false
+ }
+ return true
+ }).slice(0, MAX_SUGGESTIONS)
+ }, [datasets, layerFilter, search])
+
+ // Close the suggestions dropdown when the user clicks outside the wrapper.
+ useEffect(() => {
+ function handleClickOutside(e: MouseEvent) {
+ if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) {
+ setOpen(false)
+ }
+ }
+ document.addEventListener('mousedown', handleClickOutside)
+ return () => document.removeEventListener('mousedown', handleClickOutside)
+ }, [])
+
+ const goToCatalog = () => {
+ const query = search.trim()
+ router.push(query ? { pathname: '/catalog', query: { q: query } } : '/catalog')
+ }
+
+ return (
+
+ {datasets.length > 0 && layers.length > 2 && (
+
+ {layers.map((l) => (
+ { setLayerFilter(l); setOpen(true) }}
+ sx={
+ layerFilter !== l
+ ? { color: 'rgba(255,255,255,0.7)', borderColor: 'rgba(255,255,255,0.18)', bgcolor: 'rgba(255,255,255,0.05)', '&:hover': { borderColor: 'rgba(255,255,255,0.3)', color: '#fff' } }
+ : undefined
+ }
+ />
+ ))}
+
+ )}
+
+
+ { setSearch(e.target.value); setOpen(true) }}
+ onFocus={() => setOpen(true)}
+ sx={{
+ '& .MuiOutlinedInput-root': {
+ height: 42,
+ fontSize: 13,
+ color: '#f1f3f5',
+ bgcolor: 'rgba(255,255,255,0.06)',
+ borderRadius: '8px 0 0 8px',
+ '& fieldset': { borderColor: 'rgba(255,255,255,0.12)', borderRight: 'none' },
+ '&:hover fieldset': { borderColor: 'rgba(255,255,255,0.25)', borderRight: 'none' },
+ '&.Mui-focused': { bgcolor: 'rgba(255,255,255,0.1)' },
+ '&.Mui-focused fieldset': { borderColor: 'primary.main', borderRight: 'none' }
+ },
+ '& input::placeholder': { color: 'rgba(255,255,255,0.4)', opacity: 1 }
+ }}
+ InputProps={{
+ startAdornment: (
+
+
+
+ )
+ }}
+ />
+
+ View Catalog
+
+
+
+ {open && search.trim() && filtered.length > 0 && (
+ setOpen(false)}>
+
+ {filtered.map((d) => {
+ const key = `${d.layer}/${d.domain}/${d.dataset}`
+ return (
+ router.push(
+ `/dataset/${d.layer}/${d.domain}/${d.dataset}?version=${d.version}`
+ )}
+ sx={{
+ cursor: 'pointer',
+ px: '14px',
+ py: '10px',
+ borderBottom: '1px solid',
+ borderColor: 'divider',
+ '&:hover': { bgcolor: '#fafafa' },
+ '&:last-child': { borderBottom: 0 }
+ }}
+ >
+ {d.dataset}
+
+ {d.layer} / {d.domain} {d.version ? `v${d.version}` : ''}
+
+
+ )
+ })}
+
+
+ )}
+
+ )
+}
+
+export default DatasetSearchBar
diff --git a/frontend/src/components/ErrorBoundryComponent.tsx b/frontend/src/components/ErrorBoundryComponent.tsx
index 4a872478..83f657bd 100644
--- a/frontend/src/components/ErrorBoundryComponent.tsx
+++ b/frontend/src/components/ErrorBoundryComponent.tsx
@@ -1,48 +1,21 @@
-import { Container, Box, Typography } from '@mui/material'
-import { styled } from '@mui/material/styles'
import Link from 'next/link'
-
-const Main = styled('main')`
- display: flex;
- align-items: center;
- justify-content: center;
- min-height: 100vh;
-
- .main-content {
- background-color: ${(p) => p.theme.colors.dark1};
- flex-grow: 1;
- border-radius: inherit;
- box-shadow: 0px 4px 24px rgba(0, 0, 0, 0.25);
- color: ${(p) => p.theme.colors.white};
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- max-width: 600px !important;
- height: 200px;
- }
-`
+import { Button, Typography } from '@mui/material'
+import CenteredGradientPage from './CenteredGradientPage/CenteredGradientPage'
function ErrorBoundryComponent() {
return (
-
-
-
-
- Oops - Something Went Wrong
-
-
- If this is a regular occurance with the application please get in touch or
- raise a ticket.
-
-
-
- Go Home
-
-
-
-
-
+
+
+ Oops — Something Went Wrong
+
+
+ If this is a regular occurrence with the application please get in touch or
+ raise a ticket.
+
+
+ Go Home
+
+
)
}
diff --git a/frontend/src/components/FormActions/FormActions.tsx b/frontend/src/components/FormActions/FormActions.tsx
new file mode 100644
index 00000000..895e7340
--- /dev/null
+++ b/frontend/src/components/FormActions/FormActions.tsx
@@ -0,0 +1,32 @@
+import { Alert, Box } from '@mui/material'
+import { ReactNode } from 'react'
+
+type Props = {
+ error?: Error | null
+ bordered?: boolean
+ children: ReactNode
+}
+
+const FormActions = ({ error, bordered = true, children }: Props) => {
+ return (
+
+ {children}
+ {error && (
+
+ {error.message}
+
+ )}
+
+ )
+}
+
+export default FormActions
diff --git a/frontend/src/components/FormCard/FormCard.tsx b/frontend/src/components/FormCard/FormCard.tsx
new file mode 100644
index 00000000..9989f625
--- /dev/null
+++ b/frontend/src/components/FormCard/FormCard.tsx
@@ -0,0 +1,96 @@
+import { Alert, Box, Paper, Typography } from '@mui/material'
+import { ReactNode } from 'react'
+
+type Props = {
+ num?: number
+ title: ReactNode
+ optional?: boolean
+ headerAction?: ReactNode
+ actions?: ReactNode
+ actionsError?: Error | null
+ children: ReactNode
+ bodySx?: object
+}
+
+const FormCard = ({
+ num,
+ title,
+ optional,
+ headerAction,
+ actions,
+ actionsError,
+ children,
+ bodySx
+}: Props) => {
+ return (
+
+
+ {num !== undefined && (
+
+ {num}
+
+ )}
+
+ {title}
+ {optional && (
+
+ (optional)
+
+ )}
+
+ {headerAction && {headerAction} }
+
+ {children}
+ {actions && (
+
+ {actions}
+ {actionsError && (
+
+ {actionsError.message}
+
+ )}
+
+ )}
+
+ )
+}
+
+export default FormCard
diff --git a/frontend/src/components/Layout/AccountLayout.tsx b/frontend/src/components/Layout/AccountLayout.tsx
index d2c12272..24aa97c9 100644
--- a/frontend/src/components/Layout/AccountLayout.tsx
+++ b/frontend/src/components/Layout/AccountLayout.tsx
@@ -1,80 +1,51 @@
-import { Box, Container, LinearProgress, Toolbar } from '@mui/material'
-import { styled } from '@mui/material/styles'
-import { ComponentProps } from 'react'
-import { AppBar, Drawer } from '@/components'
-import Router from 'next/router'
+import { ComponentProps, ReactNode, useState } from 'react'
import { useQueries } from '@tanstack/react-query'
+import { getAuthStatus, getMethods } from '@/service'
import { MethodsResponse } from '@/service/types'
+import { useRouter } from 'next/router'
+import Router from 'next/router'
+import Link from 'next/link'
+import Image from 'next/image'
import {
- catalogManagementMethods,
- dataDeleteMethod,
- dataDownloadMethod,
- dataUploadMethod,
- schemaManagementMethods,
- taskManagementMethods,
- userManagementMethods
-} from '@/service/constants'
-import { getAuthStatus, getMethods } from '@/service'
-
-type Props = { title?: string } & ComponentProps
-
-const drawerWidth = 244
+ Box,
+ Drawer,
+ List,
+ ListItemButton,
+ ListItemIcon,
+ ListItemText,
+ Typography,
+ Avatar,
+ IconButton,
+ Menu,
+ MenuItem,
+ LinearProgress,
+ Divider
+} from '@mui/material'
+import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'
+import ChevronRightIcon from '@mui/icons-material/ChevronRight'
+import SearchIcon from '@mui/icons-material/Search'
+import TableChartIcon from '@mui/icons-material/TableChart'
+import WorkIcon from '@mui/icons-material/Work'
+import PeopleIcon from '@mui/icons-material/People'
+import AddBoxIcon from '@mui/icons-material/AddBox'
-const Layout = styled(Box)`
- .columns {
- display: flex;
- width: 100%;
- }
-
- main {
- width: 100%;
- }
-
- .sidebar {
- background-color: #ccc;
- position: fixed;
- width: ${drawerWidth}px;
- top: 0;
- left: 0;
- }
+const SIDEBAR_WIDTH = 240
+const SIDEBAR_COLLAPSED = 60
- .main-content {
- margin-left: ${drawerWidth}px;
- padding: ${(p) => p.theme.spacing(3)};
- width: 100%;
- }
- .MuiDrawer-paper {
- width: ${drawerWidth}px;
- }
-`
-
-const filterSidebarList = (methods: MethodsResponse) => {
- const baseMethods = []
- if (methods) {
- if (methods.can_manage_users) baseMethods.push(...userManagementMethods)
- if (methods.can_upload || methods.can_download) {
- baseMethods.push({ text: 'Data Management' })
- if (methods.can_download) baseMethods.push(...dataDownloadMethod)
- if (methods.can_upload) {
- baseMethods.push(...dataUploadMethod)
- }
- if (methods.can_create_schema) {
- baseMethods.push(...dataDeleteMethod)
- baseMethods.push(...schemaManagementMethods)
- }
- baseMethods.push(...taskManagementMethods)
- }
- if (methods.can_search_catalog) baseMethods.push(...catalogManagementMethods)
- }
+type AccountLayoutProps = {
+ title?: string
+ topbarActions?: ReactNode
+ noPad?: boolean
+ children: ReactNode
+} & Omit, 'children' | 'title'>
- return baseMethods
-}
+const AccountLayout = ({ children, title, topbarActions, noPad }: AccountLayoutProps) => {
+ const [collapsed, setCollapsed] = useState(false)
+ const [anchorEl, setAnchorEl] = useState(null)
+ const router = useRouter()
-const AccountLayout = ({ children, title, ...props }: Props) => {
const redirect = () => {
- Router.replace({
- pathname: '/login'
- })
+ Router.replace({ pathname: '/login' })
}
const results = useQueries({
@@ -82,55 +53,308 @@ const AccountLayout = ({ children, title, ...props }: Props) => {
{
queryKey: ['authStatus'],
queryFn: getAuthStatus,
- keepPreviousData: false,
- cacheTime: 0,
- refetchInterval: 0,
- onError: () => {
- redirect()
- },
- onSuccess: (data) => {
- const { detail } = data
- if (detail === 'fail') {
- redirect()
- }
+ keepPreviousData: true,
+ staleTime: Infinity,
+ refetchOnWindowFocus: false,
+ onError: () => redirect(),
+ onSuccess: (data: { detail: string }) => {
+ if (data.detail === 'fail') redirect()
}
},
{
queryKey: ['methods'],
queryFn: getMethods,
- keepPreviousData: false,
- cacheTime: 0,
- refetchInterval: 0
+ keepPreviousData: true,
+ staleTime: Infinity,
+ refetchOnWindowFocus: false
}
]
})
- if (results[0].isLoading || results[1].isLoading) {
- return
+ const methods: MethodsResponse | undefined = results[1].data
+
+ if (results[0].isLoading) {
+ return
}
- const allowedDrawerMethods = filterSidebarList(results[1].data)
+ const sidebarWidth = collapsed ? SIDEBAR_COLLAPSED : SIDEBAR_WIDTH
+ const username = methods?.username ?? null
+ const initials = username ? username.slice(0, 2).toUpperCase() : null
+
+ const hasDataSection =
+ methods?.can_upload ||
+ methods?.can_download ||
+ methods?.can_search_catalog ||
+ methods?.can_create_schema
+
+ const hasJobsSection = methods?.can_upload || methods?.can_download
+
+ function isActive(paths: string[]) {
+ return paths.some((p) => {
+ if (p === '/') return router.asPath === '/'
+ return router.asPath.startsWith(p)
+ })
+ }
return (
-
-
+ {/* Sidebar */}
+
-
-
-
-
-
-
- {children}
+ >
+ {/* Logo + collapse toggle */}
+
+
+
+
+ setCollapsed((c) => !c)}
+ sx={{
+ width: 24,
+ height: 24,
+ ml: 'auto',
+ color: '#6b7280',
+ borderRadius: 1,
+ '&:hover': { bgcolor: 'rgba(0,0,0,0.08)', color: '#374151' }
+ }}
+ aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
+ >
+ {collapsed ? : }
+
+
+
+ {/* Nav sections */}
+
+ {hasDataSection && (
+
+ {!collapsed && (
+
+ Data
+
+ )}
+
+ {methods?.can_search_catalog && (
+ } label="Catalog" active={isActive(['/catalog'])} collapsed={collapsed} />
+ )}
+ {methods?.can_create_schema && (
+ } label="Add New Dataset" active={isActive(['/schema/create'])} collapsed={collapsed} />
+ )}
+
+
+ )}
+
+ {hasJobsSection && (
+
+ {!collapsed && (
+
+ Jobs
+
+ )}
+
+ } label="Jobs" active={isActive(['/tasks'])} collapsed={collapsed} />
+
+
+ )}
+
+ {methods?.can_manage_users && (
+
+ {!collapsed && (
+
+ Admin
+
+ )}
+
+ } label="User Admin" active={isActive(['/subject'])} collapsed={collapsed} />
+
+
+ )}
+
+
+ {/* Footer */}
+
+ {!collapsed && (
+
+ {[
+ { label: 'Docs', href: 'https://rapid.readthedocs.io/en/latest/' },
+ { label: 'API Docs', href: '/api/docs' },
+ { label: 'Source Code', href: 'https://github.com/no10ds/rapid' }
+ ].map((link) => (
+
+ {link.label}
+
+ ))}
+
+ )}
+ setAnchorEl(e.currentTarget)}
+ >
+
+ {initials ?? '?'}
+
+ {!collapsed && (
+
+ {username && {username} }
+
+ {methods?.can_manage_users ? 'User Admin' : 'Data User'}
+
+
+ )}
+ setAnchorEl(null)}
+ anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
+ transformOrigin={{ vertical: 'bottom', horizontal: 'left' }}
+ >
+
+ Sign out
+
+
-
-
+
+
+ {/* Main content */}
+
+ {/* Topbar */}
+
+
+ {title}
+
+
+ {topbarActions}
+
+
+ {/* Content */}
+
+ {children}
+
+
+
+ )
+}
+
+function NavItem({ href, icon, label, active, collapsed }: { href: string; icon: ReactNode; label: string; active: boolean; collapsed: boolean }) {
+ return (
+
+
+ {icon}
+
+ {!collapsed && (
+
+ )}
+
)
}
diff --git a/frontend/src/components/PermissionsTable/PermissionsTable.tsx b/frontend/src/components/PermissionsTable/PermissionsTable.tsx
index 006110d7..5de71e29 100644
--- a/frontend/src/components/PermissionsTable/PermissionsTable.tsx
+++ b/frontend/src/components/PermissionsTable/PermissionsTable.tsx
@@ -1,356 +1,298 @@
-import { Select } from '@/components'
-import { Button } from '@/components'
-import { zodResolver } from '@hookform/resolvers/zod'
-import { Typography } from '@mui/material'
-import { Controller, useForm, FieldValues } from 'react-hook-form'
-import { z } from 'zod'
import { Permission, ActionEnum, SensitivityEnum } from '@/service'
-import { isDataPermission } from '@/service/permissions'
import { PermissionUiResponse } from '@/service/types'
-import { useEffect, useState } from 'react'
+import { useState } from 'react'
+import { ArrayPath, FieldValues, UseFieldArrayReturn } from 'react-hook-form'
import { cloneDeep } from 'lodash'
-import Table from '@mui/material/Table'
-import TableBody from '@mui/material/TableBody'
-import TableCell from '@mui/material/TableCell'
-import TableContainer from '@mui/material/TableContainer'
-import TableHead from '@mui/material/TableHead'
-import TableRow from '@mui/material/TableRow'
+import { z } from 'zod'
+import {
+ Box,
+ Button,
+ Select,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Typography
+} from '@mui/material'
type ActionType = z.infer
type PermissionType = z.infer
type SensitivityType = z.infer
-const PermissionsTable = ({
+const PermissionsTable = <
+ TFieldValues extends FieldValues,
+ TName extends ArrayPath
+>({
permissionsListData,
fieldArrayReturn,
isModifyPage = false
}: {
permissionsListData: PermissionUiResponse
- fieldArrayReturn: FieldValues
+ fieldArrayReturn: UseFieldArrayReturn
isModifyPage?: boolean
}) => {
- const [filteredPermissionsListData, setFilteredPermissionsListData] = useState({})
- const [permissionsAtMax, setPermissionsAtMax] = useState(false)
- const [isDisabled, setIsDisabled] = useState(false)
-
- const removePermissionAsAnOption = (
- permission: PermissionType,
- permissionsList: PermissionUiResponse
- ) => {
- const { type, layer, sensitivity, domain } = permission
- const typeList = permissionsList[type]
- const layerList = typeList?.[layer]
- const sensitivityList = layerList?.[sensitivity]
-
- switch (true) {
- // Scenario for protected permission
- case Boolean(domain):
- // Remove the domain
- if (domain in sensitivityList) {
- delete sensitivityList[domain]
- }
-
- // Remove the sensitivity if there are no domains left
- if (!Object.keys(sensitivityList)?.length) {
- delete layerList[sensitivity]
-
- // Remove the layer if there are no sensitivities left
- if (!Object.keys(layerList)?.length) {
- delete typeList[layer]
- }
- }
- break
- case Boolean(sensitivity):
- // Remove the sensitivity
- if (sensitivity in layerList) {
- delete layerList[sensitivity]
- }
-
- // Remove the layer if there are no sensitivities left
- if (!Object.keys(layerList)?.length || sensitivity === 'ALL') {
- delete typeList[layer]
-
- // Remove the type if there are no layers left
- if (!Object.keys(typeList)?.length || layer === 'ALL') {
- delete permissionsList[type]
- }
- }
- break
-
- // Scenario for admin permissions
- default:
- delete permissionsList[type]
- break
- }
-
- return permissionsList
- }
-
const { fields, append, remove } = fieldArrayReturn
+ const permissionFields = fields as unknown as PermissionType[]
- const { control, trigger, watch, reset, setError, setValue } = useForm({
- resolver: zodResolver(Permission)
- })
+ const [addType, setAddType] = useState('')
+ const [addLayer, setAddLayer] = useState('')
+ const [addSensitivity, setAddSensitivity] = useState('')
+ const [addDomain, setAddDomain] = useState('')
+ const [addError, setAddError] = useState('')
- // Remove any of the selected permissions from being an option
- useEffect(() => {
- let amendedPermissions = cloneDeep(permissionsListData)
- // Handle the unique case where if the user has conflicting permissions that would not be allowed
- // by the removePermissionAsAnOption function, we gracefully handle this error
+ const filteredPerms = (() => {
try {
- fields.forEach((permission) => {
- amendedPermissions = removePermissionAsAnOption(permission, amendedPermissions)
- })
+ return permissionFields.reduce(
+ (acc, perm) => removePermOption(perm, acc),
+ cloneDeep(permissionsListData)
+ )
} catch (error) {
- // Do not allow for this case when creating a user
- if (!isModifyPage) {
- throw error
- }
- }
- setFilteredPermissionsListData(amendedPermissions)
- }, [fields, permissionsListData, isModifyPage])
-
- // Set Permissions at max
- useEffect(() => {
- if (Object.keys(filteredPermissionsListData).length === 0) {
- setPermissionsAtMax(true)
- } else {
- setPermissionsAtMax(false)
+ if (!isModifyPage) throw error
+ return cloneDeep(permissionsListData)
}
- // console.log(filteredPermissionsListData)
- }, [filteredPermissionsListData])
+ })()
- const generateOptions = (items) =>
- items.map((item) => {
- return (
-
- {item}
-
- )
- })
+ const typePerms =
+ addType && filteredPerms?.[addType]
+ ? (filteredPerms[addType] as Record>>)
+ : undefined
+ const layerPerms = addLayer && typePerms?.[addLayer] ? typePerms[addLayer] : undefined
+ const domainPerms =
+ addSensitivity === 'PROTECTED' && layerPerms?.['PROTECTED']
+ ? layerPerms['PROTECTED']
+ : undefined
- useEffect(() => {
- // eslint-disable-next-line react-hooks/incompatible-library
- const subscription = watch((permissionToAdd) => {
- // If the permission is not protected, remove the domain key
- if (permissionToAdd.sensitivity !== 'PROTECTED') {
- delete permissionToAdd.domain
- }
+ const availableTypes = Object.keys(filteredPerms ?? {})
+ const availableLayers = typePerms ? Object.keys(typePerms) : []
+ const availableSensitivities = layerPerms ? Object.keys(layerPerms) : []
+ const availableDomains = domainPerms ? Object.keys(domainPerms) : []
- const allValuesDefined = Object.values(permissionToAdd).every(
- (value) => value !== undefined
- )
- const isAdminPermission = ['DATA_ADMIN', 'USER_ADMIN'].includes(permissionToAdd.type)
+ const isAdminType = addType === 'DATA_ADMIN' || addType === 'USER_ADMIN'
+ const canAdd =
+ addType !== '' &&
+ (isAdminType ||
+ (addLayer && addSensitivity && (addSensitivity !== 'PROTECTED' || addDomain)))
- setIsDisabled(!(allValuesDefined || isAdminPermission))
- })
+ function handleAdd() {
+ setAddError('')
+ if (!canAdd) {
+ setAddError('Please fill in all required fields.')
+ return
+ }
+ const perm: PermissionType = isAdminType
+ ? {
+ type: addType as 'DATA_ADMIN' | 'USER_ADMIN',
+ layer: undefined,
+ sensitivity: undefined,
+ domain: undefined
+ }
+ : {
+ type: addType as 'READ' | 'WRITE',
+ layer: addLayer,
+ sensitivity: addSensitivity as SensitivityType,
+ domain: addSensitivity === 'PROTECTED' ? addDomain : undefined
+ }
+ append(perm as Parameters[0])
+ setAddType('')
+ setAddLayer('')
+ setAddSensitivity('')
+ setAddDomain('')
+ }
- return () => subscription.unsubscribe()
- }, [watch])
+ const dash = —
return (
-
-
-
-
-
- Type
- Layer
- Sensitivity
- Domain
-
-
-
- {(fields || []).map((item, index) => (
-
-
- remove(index)}>
- Remove
-
-
-
- {item.type}
-
-
- {item.layer}
-
-
-
- {item.sensitivity}
-
-
-
- {item.domain}
-
-
- ))}
- {!permissionsAtMax && (
+
+
+
+
-
- <>
+ Type
+ Layer
+ Sensitivity
+ Domain
+
+
+
+
+ {(fields as unknown as PermissionType[]).map((perm, idx) => (
+
+ {perm.type}
+ {perm.layer ?? dash}
+ {perm.sensitivity ?? dash}
+ {perm.domain ?? dash}
+
{
- const result = trigger(undefined, { shouldFocus: true })
- if (result) {
- const permissionToAdd = watch()
- // Triggers an error if the domain is not set for protected sensitivity
- if (
- isDataPermission(permissionToAdd) &&
- permissionToAdd.sensitivity === 'PROTECTED' &&
- permissionToAdd.domain === undefined
- ) {
- setError('domain', { type: 'custom', message: 'Required' })
- } else {
- append(permissionToAdd)
- reset({
- type: undefined,
- layer: undefined,
- sensitivity: undefined,
- domain: undefined
- })
- }
- }
- }}
+ type="button"
+ size="small"
+ color="error"
+ onClick={() => remove(idx)}
+ sx={{ fontSize: 11, minWidth: 0, p: 0 }}
>
- Add
+ Remove
- >
-
-
- (
+
+
+ ))}
+
+ {availableTypes.length > 0 && (
+
+
+ {
+ setAddType(e.target.value as ActionType | '')
+ setAddLayer('')
+ setAddSensitivity('')
+ setAddDomain('')
+ }}
+ inputProps={{ 'data-testid': 'select-type' }}
+ sx={{ fontSize: 12 }}
+ >
+ Select type…
+ {availableTypes.map((t) => (
+ {t}
+ ))}
+
+
+
+ {addType && !isAdminType && (
{
+ setAddLayer(e.target.value as string)
+ setAddSensitivity('')
+ setAddDomain('')
}}
- // Reset all other values when this is changed
- onChange={(event) => {
- reset()
- setValue('type', event.target.value as ActionType)
+ inputProps={{ 'data-testid': 'select-layer' }}
+ sx={{ fontSize: 12 }}
+ >
+ Select layer…
+ {availableLayers.map((l) => (
+ {l}
+ ))}
+
+ )}
+
+
+ {addLayer && !isAdminType && (
+ {
+ setAddSensitivity(e.target.value as SensitivityType | '')
+ setAddDomain('')
}}
+ inputProps={{ 'data-testid': 'select-sensitivity' }}
+ sx={{ fontSize: 12 }}
>
- Select a permission type...
- {generateOptions(Object.keys(filteredPermissionsListData))}
+ Select sensitivity…
+ {availableSensitivities.map((s) => (
+ {s}
+ ))}
)}
- />
-
-
-
- isDataPermission(watch()) && (
-
-
- Select a layer...
-
- {generateOptions(
- Object.keys(filteredPermissionsListData[watch('type')])
- )}
-
- )
- }
- />
-
-
-
- isDataPermission(watch()) &&
- watch('layer') && (
- {
- setValue('domain', undefined)
- setValue('sensitivity', event.target.value as SensitivityType)
- }}
- >
- Select a sensitivity level...
- {generateOptions(
- Object.keys(
- filteredPermissionsListData[watch('type')][watch('layer')]
- )
- )}
-
- )
- }
- />
-
-
-
- isDataPermission(watch()) &&
- watch('sensitivity') === 'PROTECTED' && (
-
- Select a data domain...
- {isDataPermission(watch()) &&
- generateOptions(
- Object.keys(
- filteredPermissionsListData[watch('type')][watch('layer')][
- watch('sensitivity')
- ]
- )
- )}
-
- )
- }
- />
-
-
- )}
-
-
-
+
+
+ {addSensitivity === 'PROTECTED' && !isAdminType && (
+ setAddDomain(e.target.value as string)}
+ inputProps={{ 'data-testid': 'domain' }}
+ sx={{ fontSize: 12 }}
+ >
+ Select domain…
+ {availableDomains.map((d) => (
+ {d}
+ ))}
+
+ )}
+
+
+
+ + Add
+
+
+
+ )}
+
+
+
+
+ {addError && (
+ {addError}
+ )}
+
)
}
+const isEmpty = (obj: Record | undefined): boolean =>
+ !!obj && Object.keys(obj).length === 0
+
+function removePermOption(
+ permission: PermissionType,
+ permsList: Record
+): Record {
+ if (!permsList) return permsList
+ const { type, layer, sensitivity, domain } = permission as {
+ type: string
+ layer?: string
+ sensitivity?: string
+ domain?: string
+ }
+
+ // Admin perms (DATA_ADMIN / USER_ADMIN) have no layer — remove the whole type bucket.
+ if (!layer) {
+ delete permsList[type]
+ return permsList
+ }
+
+ const typeBucket = permsList[type] as Record | undefined
+ const layerBucket = typeBucket?.[layer] as Record | undefined
+
+ if (!sensitivity) return permsList
+
+ // PROTECTED perms specify a domain — remove that single domain from the sensitivity bucket.
+ if (domain) {
+ const sensitivityBucket = layerBucket?.[sensitivity] as
+ | Record
+ | undefined
+ if (sensitivityBucket && domain in sensitivityBucket) delete sensitivityBucket[domain]
+ if (isEmpty(sensitivityBucket)) delete layerBucket?.[sensitivity]
+ if (isEmpty(layerBucket)) delete typeBucket?.[layer]
+ return permsList
+ }
+
+ // Non-PROTECTED perms remove the whole sensitivity. 'ALL' also collapses its parent.
+ if (layerBucket && sensitivity in layerBucket) delete layerBucket[sensitivity]
+ const collapseLayer = isEmpty(layerBucket) || sensitivity === 'ALL'
+ if (collapseLayer) {
+ delete typeBucket?.[layer]
+ const collapseType = isEmpty(typeBucket) || layer === 'ALL'
+ if (collapseType) delete permsList[type]
+ }
+ return permsList
+}
+
export default PermissionsTable
diff --git a/frontend/src/components/SchemaCreate.tsx b/frontend/src/components/SchemaCreate.tsx
index 674ea642..cbb33b96 100644
--- a/frontend/src/components/SchemaCreate.tsx
+++ b/frontend/src/components/SchemaCreate.tsx
@@ -1,5 +1,7 @@
+import FormCard from './FormCard/FormCard'
import {
createSchema,
+ updateSchema,
schemaCreateSchema,
GlobalSensitivities,
ProtectedSensitivity
@@ -11,40 +13,46 @@ import {
SensitivityEnum
} from '@/service/types'
import { zodResolver } from '@hookform/resolvers/zod'
-import { Box, FormControl, Link, Typography } from '@mui/material'
import { useMutation } from '@tanstack/react-query'
import { useState } from 'react'
import { Controller, useForm } from 'react-hook-form'
-import Alert from './Alert/Alert'
-import Button from './Button/Button'
-import Card from './Card/Card'
-import Row from './Row'
-import Select from './Select/Select'
-import SimpleTable from './SimpleTable/SimpleTable'
-import TextField from './TextField/TextField'
+import {
+ Box,
+ Typography,
+ Button,
+ TextField,
+ Select,
+ MenuItem,
+ FormControl,
+ InputLabel,
+ FormHelperText,
+ Alert,
+ AlertTitle,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Stack,
+ IconButton,
+ Link as MuiLink
+} from '@mui/material'
+import CloseIcon from '@mui/icons-material/Close'
const dataTypes = [
- 'bigint',
- 'boolean',
- 'char',
- 'date',
- 'decimal',
- 'double',
- 'float',
- 'int',
- 'smallint',
- 'string',
- 'timestamp',
- 'tinyint',
- 'varchar'
+ 'bigint', 'boolean', 'char', 'date', 'decimal', 'double',
+ 'float', 'int', 'smallint', 'string', 'timestamp', 'tinyint', 'varchar'
]
function CreateSchema({
schemaData,
- layersData
+ layersData,
+ mode = 'create'
}: {
schemaData: GenerateSchemaResponse
layersData: string[]
+ mode?: 'create' | 'edit'
}) {
const [newSchemaData, setNewSchemaData] = useState(schemaData)
const [keyValueTag, setKeyValueTag] = useState({ key: '', value: '' })
@@ -59,479 +67,385 @@ function CreateSchema({
Error,
GenerateSchemaResponse
>({
- mutationFn: createSchema
+ mutationFn: mode === 'edit' ? updateSchema : createSchema
})
- const setNewSchemaDataMetadata = (key, value) => {
- setNewSchemaData({
- ...newSchemaData,
- metadata: {
- ...newSchemaData.metadata,
- [key]: value
- }
- })
- }
+ const setMeta = (key: string, value: unknown) =>
+ setNewSchemaData((prev) => ({ ...prev, metadata: { ...prev.metadata, [key]: value } }))
- const setNewSchemaDataColumn = (name, key, value) => {
- const newColumns = newSchemaData.columns.map((col) => {
- if (col.name === name) {
- return {
- ...col,
- [key]: value
- }
- }
- return col
- })
- setNewSchemaData({
- ...newSchemaData,
- columns: newColumns
- })
- }
+ const setCol = (name: string, key: string, value: unknown) =>
+ setNewSchemaData((prev) => ({
+ ...prev,
+ columns: prev.columns.map((c) => c.name === name ? { ...c, [key]: value } : c)
+ }))
if (isSuccess) {
return (
-
-
- {data.details}
+
+
+
+ {mode === 'edit' ? 'Schema updated — a new version has been created' : 'Dataset added successfully'}
+
+ {data.details}
-
+
)
}
- // Used to conditionally show the format field if we have a date data type in the table
- const doesTypesContainData = newSchemaData.columns.some(
- (cols) => cols.data_type === 'date'
- )
+ const hasDateColumn = newSchemaData.columns.some((c) => c.data_type === 'date')
return (
-
+
+
)
}
diff --git a/frontend/src/components/UploadProgress/UploadProgress.tsx b/frontend/src/components/UploadProgress/UploadProgress.tsx
index 451df296..28cf279d 100644
--- a/frontend/src/components/UploadProgress/UploadProgress.tsx
+++ b/frontend/src/components/UploadProgress/UploadProgress.tsx
@@ -1,33 +1,9 @@
-import { Alert, AlertColor, LinearProgress, Link, Typography } from '@mui/material'
import { UploadDatasetResponseDetails } from '@/service/types'
import { useQuery } from '@tanstack/react-query'
import { getJob } from '@/service'
import { useState, Dispatch, SetStateAction } from 'react'
-import Row from '../Row'
-
-enum UploadStatus {
- Failed = 'FAILED',
- Success = 'SUCCESS',
- InProgress = 'IN PROGRESS'
-}
-
-const statusConverter = {
- [UploadStatus.Failed]: {
- severity: 'error',
- message: 'Data upload error',
- link: 'See error details'
- },
- [UploadStatus.Success]: {
- severity: 'success',
- message: 'Data uploaded successfully',
- link: 'See upload details'
- },
- [UploadStatus.InProgress]: {
- severity: 'info',
- message: 'Data processing',
- link: 'See progress details'
- }
-}
+import { useRouter } from 'next/router'
+import { Box, Typography, LinearProgress } from '@mui/material'
const UploadProgress = ({
uploadSuccessDetails,
@@ -36,46 +12,29 @@ const UploadProgress = ({
uploadSuccessDetails: UploadDatasetResponseDetails
setDisableUpload: Dispatch>
}) => {
+ const router = useRouter()
const [stop, setStop] = useState(false)
- const [status, setStatus] = useState(UploadStatus.InProgress)
useQuery(['getJob', uploadSuccessDetails.job_id], getJob, {
onSuccess: (data) => {
- switch (data.status) {
- case UploadStatus.Success:
- case UploadStatus.Failed:
- setStop(true)
- setStatus(data.status)
- setDisableUpload(false)
- break
- default:
- break
+ if (data.status === 'SUCCESS' || data.status === 'FAILED') {
+ setStop(true)
+ setDisableUpload(false)
+ router.push(`/tasks/${uploadSuccessDetails.job_id}`)
}
},
- // Keep refetching every second
refetchInterval: stop ? false : 1000,
refetchIntervalInBackground: true,
refetchOnWindowFocus: false
})
return (
-
- Status: {statusConverter[status].message}
- {!stop && (
-
-
-
- )}
-
-
- {statusConverter[status].link}
-
-
-
+
+
+ Processing {uploadSuccessDetails.original_filename}…
+
+
+
)
}
diff --git a/frontend/src/components/index.ts b/frontend/src/components/index.ts
index 6a7dbb9f..5a603101 100644
--- a/frontend/src/components/index.ts
+++ b/frontend/src/components/index.ts
@@ -16,3 +16,6 @@ export { default as Row } from './Row'
export { default as Link } from './Link'
export { default as TableSkeleton } from './Skeleton/TableSkeleton'
export { default as CreateSchema } from './SchemaCreate'
+export { default as FormCard } from './FormCard/FormCard'
+export { default as FormActions } from './FormActions/FormActions'
+export { default as CenteredGradientPage } from './CenteredGradientPage/CenteredGradientPage'
diff --git a/frontend/src/pages/404.tsx b/frontend/src/pages/404.tsx
index f8f08363..0084ad45 100644
--- a/frontend/src/pages/404.tsx
+++ b/frontend/src/pages/404.tsx
@@ -1,44 +1,17 @@
-import { Container, Box, Typography } from '@mui/material'
-import { styled } from '@mui/material/styles'
import Link from 'next/link'
-
-const Main = styled('main')`
- display: flex;
- align-items: center;
- justify-content: center;
- min-height: 100vh;
-
- .main-content {
- background-color: ${(p) => p.theme.colors.dark1};
- flex-grow: 1;
- border-radius: inherit;
- box-shadow: 0px 4px 24px rgba(0, 0, 0, 0.25);
- color: ${(p) => p.theme.colors.white};
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- max-width: 600px !important;
- height: 200px;
- }
-`
+import { Button, Typography } from '@mui/material'
+import { CenteredGradientPage } from '@/components'
function FourOhFour() {
return (
-
-
-
-
- Oops - Page not found
-
-
-
- Go Home
-
-
-
-
-
+
+
+ Oops — Page not found
+
+
+ Go Home
+
+
)
}
diff --git a/frontend/src/pages/_app.tsx b/frontend/src/pages/_app.tsx
index 72c14957..3b11f905 100644
--- a/frontend/src/pages/_app.tsx
+++ b/frontend/src/pages/_app.tsx
@@ -2,7 +2,7 @@ import { ThemeProvider } from '@/components'
import { CacheProvider, EmotionCache } from '@emotion/react'
import createEmotionCache from '@/utils/createEmotionCache'
import { ErrorBoundary } from 'react-error-boundary'
-import { ReactNode, useEffect } from 'react'
+import { ReactNode, useEffect, useRef } from 'react'
import { AppProps } from 'next/app'
import { NextPage } from 'next'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
@@ -22,9 +22,11 @@ interface MyAppProps extends AppProps {
const clientSideEmotionCache = createEmotionCache()
const queryClient = new QueryClient({
- defaultOptions: { queries: { staleTime: 5 * 1000, cacheTime: 0, retry: false } }
+ defaultOptions: { queries: { staleTime: 30 * 1000, cacheTime: 5 * 60 * 1000, retry: false } }
})
+const ACTIVITY_EVENTS = ['mousemove', 'mousedown', 'touchstart', 'click', 'keydown'] as const
+
export default function MyApp({
Component,
emotionCache = clientSideEmotionCache,
@@ -34,47 +36,35 @@ export default function MyApp({
const { asPath } = router
const getLayout = Component.getLayout ?? ((page) => page)
- let timeout: NodeJS.Timeout | null = null
+ const timeoutRef = useRef(null)
- const isLongTimeout = () => {
- return asPath === '/data/download' || asPath === 'data/upload'
- }
+ useEffect(() => {
+ const isLongTimeout = asPath === '/data/download' || asPath === '/data/upload'
- const restartAutoReset = () => {
- if (timeout) {
- clearTimeout(timeout)
+ const restartAutoReset = () => {
+ if (timeoutRef.current) clearTimeout(timeoutRef.current)
+ timeoutRef.current = setTimeout(
+ async () => {
+ await fetch('/api/oauth2/logout', { method: 'GET', credentials: 'include' })
+ },
+ isLongTimeout ? 1800000 : 300000
+ )
}
- timeout = setTimeout(
- async () => {
- await fetch('/api/oauth2/logout', { method: 'GET', credentials: 'include' })
- },
- isLongTimeout() ? 1800000 : 300000 // 30 mins and 5 mins respectively
- )
- }
-
- useEffect(() => {
restartAutoReset()
- document.addEventListener('mousemove', restartAutoReset)
- document.addEventListener('mousedown', restartAutoReset)
- document.addEventListener('touchstart', restartAutoReset)
- document.addEventListener('click', restartAutoReset)
- document.addEventListener('keydown', restartAutoReset)
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [router.pathname])
+ ACTIVITY_EVENTS.forEach((e) => document.addEventListener(e, restartAutoReset))
+
+ return () => {
+ if (timeoutRef.current) clearTimeout(timeoutRef.current)
+ ACTIVITY_EVENTS.forEach((e) => document.removeEventListener(e, restartAutoReset))
+ }
+ }, [asPath])
return (
-
rAPId
diff --git a/frontend/src/pages/_document.tsx b/frontend/src/pages/_document.tsx
index 6bd2ce7f..020a41a7 100644
--- a/frontend/src/pages/_document.tsx
+++ b/frontend/src/pages/_document.tsx
@@ -24,6 +24,13 @@ export default class MyDocument extends Document {
+ {/* Google Fonts — Poppins (UI) + DM Mono (monospace) */}
+
+
+
{this.props.emotionStyleTags}
@@ -53,7 +60,6 @@ MyDocument.getInitialProps = async (ctx) => {
))
diff --git a/frontend/src/pages/catalog/[search].tsx b/frontend/src/pages/catalog/[search].tsx
index f686eb74..9a0e4bce 100644
--- a/frontend/src/pages/catalog/[search].tsx
+++ b/frontend/src/pages/catalog/[search].tsx
@@ -1,9 +1,40 @@
-import { AccountLayout, Card, SimpleTable } from '@/components'
+import AccountLayout from '@/components/Layout/AccountLayout'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
import { getMetadataSearch } from '@/service'
-import { Chip, LinearProgress, Typography } from '@mui/material'
import { useQuery } from '@tanstack/react-query'
import { useRouter } from 'next/router'
+import Link from 'next/link'
+import { ReactNode } from 'react'
+import {
+ Box,
+ Paper,
+ Typography,
+ Button,
+ Chip,
+ LinearProgress,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow
+} from '@mui/material'
+
+type MatchField = 'columns' | 'dataset' | 'description'
+
+function getMatchLabel(type: MatchField) {
+ if (type === 'columns') return 'Column'
+ if (type === 'dataset') return 'Dataset Title'
+ if (type === 'description') return 'Description'
+ return type
+}
+
+function getMatchColor(type: MatchField): 'error' | 'info' | 'warning' | 'default' {
+ if (type === 'columns') return 'error'
+ if (type === 'dataset') return 'info'
+ if (type === 'description') return 'warning'
+ return 'default'
+}
function GetSearch() {
const router = useRouter()
@@ -12,13 +43,11 @@ function GetSearch() {
const { isLoading, data, error } = useQuery(
['metadataSearch', search],
getMetadataSearch,
- {
- refetchOnMount: false
- }
+ { refetchOnMount: false }
)
if (isLoading) {
- return
+ return
}
if (error) {
@@ -27,73 +56,69 @@ function GetSearch() {
if (!data.length) {
return (
-
-
- No Results Found
-
- Try a less specific query
-
+
+ No Results Found
+ Try a less specific query
+ ← Back to Catalog
+
)
}
- const getChipLabel = (type) => {
- if (type === 'columns') {
- return 'Column'
- } else if (type === 'dataset') {
- return 'Dataset Title'
- } else if (type === 'description') {
- return 'Description'
- }
- }
-
- const getChipColor = (type) => {
- if (type === 'columns') {
- return 'error'
- } else if (type === 'dataset') {
- return 'primary'
- } else if (type === 'description') {
- return 'warning'
- }
- }
-
return (
-
-
- Data Catalog Search
-
- Search Term - {search}
+
+
+
+ ← Back to Catalog
+
+
+ Results for “{search}”
+
+
- {
- return [
- { children: item.domain },
- { children: item.dataset },
- { children: item.version },
- { children: item.matching_data },
- {
- children: (
-
- )
- }
- ]
- })}
- headers={[
- { children: 'Dataset Domain' },
- { children: 'Dataset Title' },
- { children: 'Version' },
- { children: 'Match Result' },
- { children: 'Type' }
- ]}
- />
-
+
+
+
+
+
+ Dataset Domain
+ Dataset Title
+ Version
+ Match Result
+ Type
+
+
+
+ {data.map((item, idx) => (
+
+ {item.domain}
+ {item.dataset}
+ {item.version}
+ {item.matching_data}
+
+
+
+
+ ))}
+
+
+
+
+
+ Showing {data.length} result{data.length !== 1 ? 's' : ''} for “{search}”
+
+
+
+
)
}
export default GetSearch
-GetSearch.getLayout = (page) => {page}
+GetSearch.getLayout = (page: ReactNode) => (
+ {page}
+)
diff --git a/frontend/src/pages/catalog/index.tsx b/frontend/src/pages/catalog/index.tsx
index eac36404..2ad936bd 100644
--- a/frontend/src/pages/catalog/index.tsx
+++ b/frontend/src/pages/catalog/index.tsx
@@ -1,66 +1,246 @@
-import { MetadataSearchRequest } from '@/service/types'
-import { AccountLayout, Button, Row, Card, TextField } from '@/components'
-import { zodResolver } from '@hookform/resolvers/zod'
-import { Typography } from '@mui/material'
+import AccountLayout from '@/components/Layout/AccountLayout'
+import ErrorCard from '@/components/ErrorCard/ErrorCard'
+import LayerChip from '@/components/Chip/LayerChip'
+import { formatDate } from '@/utils/date'
+import { sortByString } from '@/utils/sort'
+import { getDatasetsUi } from '@/service'
+import { Dataset } from '@/service/types'
+import { useQuery } from '@tanstack/react-query'
import { useRouter } from 'next/router'
-import { useForm, Controller } from 'react-hook-form'
-import { z } from 'zod'
+import Link from 'next/link'
+import { ReactNode, useState, useMemo } from 'react'
+import {
+ Box,
+ Paper,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ TableSortLabel,
+ TextField,
+ Select,
+ MenuItem,
+ Chip,
+ Pagination,
+ Typography,
+ LinearProgress,
+ InputAdornment
+} from '@mui/material'
+import SearchIcon from '@mui/icons-material/Search'
+
+const PAGE_SIZE = 20
+
+type SortCol = 'domain' | 'dataset' | 'last_updated' | 'last_uploaded_by'
function CatalogPage() {
const router = useRouter()
- const { control, handleSubmit } = useForm({
- resolver: zodResolver(
- z.object({
- search: z.string()
- })
- )
- })
+ const initialSearch = typeof router.query.q === 'string' ? router.query.q : ''
+
+ const [layerFilter, setLayerFilter] = useState('All')
+ const [domainFilter, setDomainFilter] = useState('All')
+ const [search, setSearch] = useState(initialSearch)
+ const [page, setPage] = useState(1)
+ const [sortCol, setSortCol] = useState(null)
+ const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc')
+
+ const { data: datasetsList, error } = useQuery(
+ ['datasetsList', 'READ'],
+ getDatasetsUi
+ )
+
+ const layers = useMemo(() => {
+ if (!datasetsList) return ['All']
+ const unique = Array.from(new Set((datasetsList as Dataset[]).map((d) => d.layer).filter(Boolean))).sort()
+ return ['All', ...unique]
+ }, [datasetsList])
+
+ const domains = useMemo(() => {
+ if (!datasetsList) return []
+ const all = Array.from(new Set((datasetsList as Dataset[]).map((d) => d.domain))).sort()
+ return ['All', ...all]
+ }, [datasetsList])
+
+ const filtered = useMemo(() => {
+ if (!datasetsList) return []
+ return (datasetsList as Dataset[]).filter((d) => {
+ if (layerFilter !== 'All' && d.layer?.toLowerCase() !== layerFilter.toLowerCase()) return false
+ if (domainFilter !== 'All' && d.domain !== domainFilter) return false
+ if (search.trim()) {
+ const q = search.trim().toLowerCase()
+ if (!d.dataset.toLowerCase().includes(q)) return false
+ }
+ return true
+ })
+ }, [datasetsList, layerFilter, domainFilter, search])
+
+ const sorted = useMemo(
+ () => sortByString(filtered, sortCol, sortDir),
+ [filtered, sortCol, sortDir]
+ )
+
+ const totalPages = Math.max(1, Math.ceil(sorted.length / PAGE_SIZE))
+ const safePage = Math.min(page, totalPages)
+ const pageItems = sorted.slice((safePage - 1) * PAGE_SIZE, safePage * PAGE_SIZE)
+
+ function handleSort(col: SortCol) {
+ if (sortCol === col) {
+ setSortDir((d) => d === 'asc' ? 'desc' : 'asc')
+ } else {
+ setSortCol(col)
+ setSortDir(col === 'domain' || col === 'dataset' ? 'asc' : 'desc')
+ }
+ setPage(1)
+ }
+
+ if (error) return
return (
-
+ )}
+
+
)
}
export default CatalogPage
-CatalogPage.getLayout = (page) => (
+CatalogPage.getLayout = (page: ReactNode) => (
{page}
)
diff --git a/frontend/src/pages/data/delete/index.tsx b/frontend/src/pages/data/delete/index.tsx
index 050140a7..eb38c16c 100644
--- a/frontend/src/pages/data/delete/index.tsx
+++ b/frontend/src/pages/data/delete/index.tsx
@@ -1,14 +1,29 @@
-import { AccountLayout, Alert, Button, Card } from '@/components'
+import { AccountLayout, FormCard } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
import DatasetSelector from '@/components/DatasetSelector/DatasetSelector'
import { deleteDataset, getDatasetsUi } from '@/service'
import { Dataset, DeleteDatasetResponse } from '@/service/types'
-import { LinearProgress, Typography } from '@mui/material'
import { useMutation, useQuery } from '@tanstack/react-query'
-import { useState } from 'react'
+import { useRouter } from 'next/router'
+import { useState, ReactNode } from 'react'
+import { Box, Alert, AlertTitle, Button, Chip, LinearProgress } from '@mui/material'
function DeleteDataset({ datasetInput = null }: { datasetInput?: Dataset | null }) {
- const [dataset, setDataset] = useState(datasetInput)
+ const router = useRouter()
+ const { layer, domain, dataset: datasetName } = router.query ?? {}
+
+ const fromQuery: Dataset | null =
+ layer && domain && datasetName
+ ? {
+ layer: layer as string,
+ domain: domain as string,
+ dataset: datasetName as string,
+ version: 1,
+ sensitivity: undefined
+ }
+ : null
+
+ const [dataset, setDataset] = useState(datasetInput ?? fromQuery)
const [deleteDatasetSuccessDetails, setDeleteDatasetSuccessDetails] = useState<
string | undefined
>()
@@ -25,16 +40,12 @@ function DeleteDataset({ datasetInput = null }: { datasetInput?: Dataset | null
{ path: string }
>({
mutationFn: deleteDataset,
- onMutate: () => {
- setDeleteDatasetSuccessDetails(undefined)
- },
- onSuccess: (data) => {
- setDeleteDatasetSuccessDetails(data.details)
- }
+ onMutate: () => setDeleteDatasetSuccessDetails(undefined),
+ onSuccess: (data) => setDeleteDatasetSuccessDetails(data.details)
})
if (isDatasetsListLoading) {
- return
+ return
}
if (datasetsError) {
@@ -42,7 +53,9 @@ function DeleteDataset({ datasetInput = null }: { datasetInput?: Dataset | null
}
return (
-
+
+
)
}
export default DeleteDataset
-DeleteDataset.getLayout = (page) => (
+DeleteDataset.getLayout = (page: ReactNode) => (
{page}
)
diff --git a/frontend/src/pages/data/download/[layer]/[domain]/[dataset].tsx b/frontend/src/pages/data/download/[layer]/[domain]/[dataset].tsx
index 89805dbb..597ebc97 100644
--- a/frontend/src/pages/data/download/[layer]/[domain]/[dataset].tsx
+++ b/frontend/src/pages/data/download/[layer]/[domain]/[dataset].tsx
@@ -1,22 +1,29 @@
-import {
- AccountLayout,
- Button,
- Card,
- Link,
- Row,
- Select,
- SimpleTable,
- TextField,
- Alert
-} from '@/components'
+import { AccountLayout, FormCard } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
-import { asVerticalTableList } from '@/utils'
+import { formatDate } from '@/utils/date'
+import { triggerBlobDownload } from '@/utils/download'
+import { buildQueryPayload } from '@/utils/query'
import { getDatasetInfo, queryDataset } from '@/service'
import { DataFormats } from '@/service/types'
-import { Typography, LinearProgress } from '@mui/material'
import { useMutation, useQuery } from '@tanstack/react-query'
import { useRouter } from 'next/router'
-import { useState } from 'react'
+import { useState, ReactNode } from 'react'
+import Link from 'next/link'
+import {
+ Box,
+ Typography,
+ Button,
+ Chip,
+ Alert,
+ LinearProgress,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ TextField
+} from '@mui/material'
function DownloadDataset() {
const router = useRouter()
@@ -47,18 +54,10 @@ function DownloadDataset() {
{ path: string; dataFormat: DataFormats; data: unknown }
>({
mutationFn: queryDataset,
- onSuccess: async (response, { dataFormat }) => {
+ onSuccess: async (response, { dataFormat: fmt }) => {
if (response.status === 200) {
setNoContentReturn(false)
- const blob = await response.blob()
- const url = window.URL.createObjectURL(blob)
- const a = document.createElement('a')
- a.style.display = 'none'
- a.href = url
- a.download = `${layer}_${domain}_${dataset}_${version}.${dataFormat}`
- document.body.appendChild(a)
- a.click()
- window.URL.revokeObjectURL(url)
+ triggerBlobDownload(await response.blob(), `${layer}_${domain}_${dataset}_${version}.${fmt}`)
} else if (response.status === 204) {
setNoContentReturn(true)
}
@@ -66,209 +65,167 @@ function DownloadDataset() {
})
if (isDatasetInfoLoading) {
- return
+ return
}
if (datasetInfoError) {
return
}
- const addListValueToQuery = (queryBody, key, value) => {
- if (value) {
- queryBody[key] = value.split(',')
- }
- }
-
- const addStringValueToQuery = (queryBody, key, value) => {
- if (value) {
- queryBody[key] = value
- }
- }
-
- const createQueryBodyData = () => {
- const queryBodyData = {}
- addListValueToQuery(queryBodyData, 'select_columns', queryBody.select_columns)
- addStringValueToQuery(queryBodyData, 'filter', queryBody.filter)
- addListValueToQuery(queryBodyData, 'group_by_columns', queryBody.group_by_columns)
- addStringValueToQuery(
- queryBodyData,
- 'aggregation_conditions',
- queryBody.aggregation_conditions
- )
- addStringValueToQuery(queryBodyData, 'limit', queryBody.limit)
- return queryBodyData
- }
+const overviewRows: [string, string][] = [
+ ['Domain', domain as string],
+ ['Dataset', dataset as string],
+ ['Description', datasetInfoData.metadata.description],
+ ['Version', version as string],
+ ['Last updated', formatDate(datasetInfoData.metadata.last_updated)],
+ ['Last uploaded by', datasetInfoData.metadata.last_uploaded_by || 'Unknown'],
+ ['Number of rows', datasetInfoData.metadata.number_of_rows?.toString()],
+ ['Number of columns', datasetInfoData.metadata.number_of_columns?.toString()]
+ ]
+
+ const queryFields = [
+ { key: 'select_columns', label: 'Select Columns', placeholder: 'column1, avg(column2)' },
+ { key: 'filter', label: 'Filter', placeholder: 'column >= 10' },
+ { key: 'group_by_columns', label: 'Group by Columns', placeholder: 'column1, column3' },
+ {
+ key: 'aggregation_conditions',
+ label: 'Aggregation Conditions',
+ placeholder: 'avg(column2) <= 15'
+ },
+ { key: 'limit', label: 'Row Limit', placeholder: '30' }
+ ] as const
return (
-
- mutate({
- path: `${layer}/${domain}/${dataset}/query?version=${version}`,
- dataFormat,
- data: createQueryBodyData()
- })
- }
- loading={isLoading}
- >
- Download
-
- }
- >
-
- Dataset Overview
-
-
-
-
-
- Columns
-
- {
- return [
- { children: column.name },
- { children: column.data_type },
- { children: column.allow_null ? 'True' : 'False' },
- { children: column.unique ? 'True' : 'False' },
- { children: column.statistics ? column.statistics.max : '-' },
- { children: column.statistics ? column.statistics.min : '-' }
- ]
- })}
- />
-
- Format
-
-
- setDataFormat(e.target.value as DataFormats)}
- />
-
-
-
- Query (optional)
-
-
-
- For further information on writing queries consult the{' '}
-
- query writing guide
-
-
-
-
- Select Columns
-
- setQueryBody({ ...queryBody, select_columns: event.target.value })
- }
- />
-
-
-
- Filter
- setQueryBody({ ...queryBody, filter: event.target.value })}
- />
-
-
-
- Group by Columns
-
- setQueryBody({ ...queryBody, group_by_columns: event.target.value })
- }
- />
-
-
-
- Aggregation Conditions
-
- setQueryBody({ ...queryBody, aggregation_conditions: event.target.value })
- }
- />
-
-
-
- Row Limit
- setQueryBody({ ...queryBody, limit: event.target.value })}
- />
-
+
+
+
+
+
+ {overviewRows.map(([k, v]) => (
+
+
+ {k}
+
+ {v}
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+ Name
+ Data Type
+ Allows Null
+ Is Unique
+ Max
+ Min
+
+
+
+ {datasetInfoData.columns.map((column, idx) => (
+
+ {column.name}
+ {column.data_type}
+ {column.allow_null ? 'Yes' : 'No'}
+ {column.unique ? 'Yes' : 'No'}
+
+ {column.statistics ? column.statistics.max : '—'}
+
+
+ {column.statistics ? column.statistics.min : '—'}
+
+
+ ))}
+
+
+
+
+
+
+
+ For further information on writing queries consult the{' '}
+
+ query writing guide
+
+
+
+ {queryFields.map(({ key, label, placeholder }) => (
+ setQueryBody({ ...queryBody, [key]: e.target.value })}
+ InputLabelProps={{ shrink: true }}
+ />
+ ))}
+
+
+
+
+
+ mutate({
+ path: `${layer}/${domain}/${dataset}/query?version=${version}`,
+ dataFormat,
+ data: buildQueryPayload(queryBody)
+ })
+ }
+ >
+ {isLoading ? 'Downloading…' : 'Download'}
+
+
+ Back
+
+ >
+ }
+ >
+
+ {(['csv', 'json'] as DataFormats[]).map((fmt) => (
+ setDataFormat(fmt)}
+ variant={dataFormat === fmt ? 'filled' : 'outlined'}
+ color={dataFormat === fmt ? 'primary' : 'default'}
+ />
+ ))}
+
+
{noContentReturn && (
-
- {
- 'No data returned for this query. Please ensure that data has been uploaded and the query is not too restrictive.'
- }
-
- )}
- {error && (
-
- {error?.message}
+
+ No data returned for this query. Please ensure that data has been uploaded and the
+ query is not too restrictive.
)}
-
+ {error && {error?.message} }
+
)
}
export default DownloadDataset
-DownloadDataset.getLayout = (page) => (
+DownloadDataset.getLayout = (page: ReactNode) => (
{page}
)
diff --git a/frontend/src/pages/data/download/file.tsx b/frontend/src/pages/data/download/file.tsx
index 7dc9ded0..7fdaa449 100644
--- a/frontend/src/pages/data/download/file.tsx
+++ b/frontend/src/pages/data/download/file.tsx
@@ -8,7 +8,6 @@ import {
Row,
TextField
} from '@/components'
-import { Typography } from '@mui/material'
import { useRouter } from 'next/router'
import { asVerticalTableList } from '@/utils'
@@ -18,9 +17,7 @@ function FilePage() {
return (
Download}>
-
- Dataset Overview
-
+ Dataset Overview
-
- Columns
-
+ Columns
-
- Format
-
+ Format
-
- Query (optional)
-
+ Query (optional)
-
+
For further information on writing queries consult the{' '}
query writing guide
-
+
- Select Columns
+ Select Columns
- Filter
+ Filter
- Group by Columns
+ Group by Columns
- Aggregation Conditions
+ Aggregation Conditions
- Row Limit
+ Row Limit
diff --git a/frontend/src/pages/data/download/index.tsx b/frontend/src/pages/data/download/index.tsx
index 9922e7b4..4a3cd6c8 100644
--- a/frontend/src/pages/data/download/index.tsx
+++ b/frontend/src/pages/data/download/index.tsx
@@ -1,13 +1,12 @@
-import { Card, Button } from '@/components'
+import { AccountLayout, FormCard } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
-import AccountLayout from '@/components/Layout/AccountLayout'
+import DatasetSelector from '@/components/DatasetSelector/DatasetSelector'
import { getDatasetsUi } from '@/service'
-import { Typography, LinearProgress } from '@mui/material'
+import { Dataset } from '@/service/types'
import { useQuery } from '@tanstack/react-query'
import { useRouter } from 'next/router'
-import { useState } from 'react'
-import DatasetSelector from '@/components/DatasetSelector/DatasetSelector'
-import { Dataset } from '@/service/types'
+import { useState, ReactNode } from 'react'
+import { Box, Paper, Typography, Button, Chip, LinearProgress } from '@mui/material'
function DownloadData({ datasetInput = null }: { datasetInput?: Dataset | null }) {
const router = useRouter()
@@ -20,7 +19,7 @@ function DownloadData({ datasetInput = null }: { datasetInput?: Dataset | null }
} = useQuery(['datasetsList', 'READ'], getDatasetsUi)
if (isDatasetsListLoading) {
- return
+ return
}
if (datasetsError) {
@@ -29,51 +28,60 @@ function DownloadData({ datasetInput = null }: { datasetInput?: Dataset | null }
if (Object.keys(datasetsList).length === 0) {
return (
-
-
+
+
You currently do not have any data to download. Get started by creating a schema
and uploading a dataset that you want to store in rAPId.
-
+
All datasets will then become available to be downloaded from here.
-
+
)
}
+ const datasetLabel = dataset
+ ? `${dataset.layer} / ${dataset.domain} / ${dataset.dataset}`
+ : null
+
return (
-
- dataset &&
- router.push(
- `/data/download/${dataset.layer}/${dataset.domain}/${dataset.dataset}?version=${dataset.version}`
- )
- }
- >
- Next
-
- }
+ {
+ event.preventDefault()
+ if (dataset) {
+ router.push(
+ `/data/download/${dataset.layer}/${dataset.domain}/${dataset.dataset}?version=${dataset.version}`
+ )
+ }
+ }}
>
-
- Download the contents of a datasource from rAPId. Select the relevant dataset you
- want to download and then the version to download from. Please note it might take
- some time to for the API to query the dataset especially if they are large.
-
-
-
+
+
+ Next
+
+ {datasetLabel && (
+
+ )}
+ >
+ }
+ >
+
+ Download the contents of a datasource from rAPId. Select the relevant dataset
+ and version to download from. Large datasets may take some time to query.
+
+
+
+
)
}
export default DownloadData
-DownloadData.getLayout = (page) => (
+DownloadData.getLayout = (page: ReactNode) => (
{page}
)
diff --git a/frontend/src/pages/data/upload/index.tsx b/frontend/src/pages/data/upload/index.tsx
index 6075d503..dc2d7f74 100644
--- a/frontend/src/pages/data/upload/index.tsx
+++ b/frontend/src/pages/data/upload/index.tsx
@@ -1,17 +1,19 @@
-import { Card, Row, Button, Alert } from '@/components'
+import { AccountLayout, FormCard } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
-import AccountLayout from '@/components/Layout/AccountLayout'
-import UploadProgress from '@/components/UploadProgress/UploadProgress'
import DatasetSelector from '@/components/DatasetSelector/DatasetSelector'
+import UploadProgress from '@/components/UploadProgress/UploadProgress'
import { getDatasetsUi, uploadDataset } from '@/service'
import {
Dataset,
UploadDatasetResponse,
UploadDatasetResponseDetails
} from '@/service/types'
-import { Typography, LinearProgress } from '@mui/material'
import { useMutation, useQuery } from '@tanstack/react-query'
-import { useState } from 'react'
+import { useState, ReactNode } from 'react'
+import Link from 'next/link'
+import { Box, Typography, Button, Chip, Alert, LinearProgress } from '@mui/material'
+import CloudUploadIcon from '@mui/icons-material/CloudUpload'
+import AddIcon from '@mui/icons-material/Add'
function UploadDataset({ datasetInput = null }: { datasetInput?: Dataset | null }) {
const [file, setFile] = useState()
@@ -43,15 +45,21 @@ function UploadDataset({ datasetInput = null }: { datasetInput?: Dataset | null
})
if (isDatasetsListLoading) {
- return
+ return
}
if (datasetsError) {
return
}
+ const datasetLabel = dataset
+ ? `${dataset.layer} / ${dataset.domain} / ${dataset.dataset}`
+ : null
+
return (
-
+
+
)
}
export default UploadDataset
-UploadDataset.getLayout = (page) => {page}
+UploadDataset.getLayout = (page: ReactNode) => (
+ {page}
+)
diff --git a/frontend/src/pages/dataset/[layer]/[domain]/[dataset].tsx b/frontend/src/pages/dataset/[layer]/[domain]/[dataset].tsx
new file mode 100644
index 00000000..02f1f56f
--- /dev/null
+++ b/frontend/src/pages/dataset/[layer]/[domain]/[dataset].tsx
@@ -0,0 +1,417 @@
+import { AccountLayout, FormCard } from '@/components'
+import ErrorCard from '@/components/ErrorCard/ErrorCard'
+import LayerChip from '@/components/Chip/LayerChip'
+import UploadProgress from '@/components/UploadProgress/UploadProgress'
+import { formatDate } from '@/utils/date'
+import { triggerBlobDownload } from '@/utils/download'
+import { buildQueryPayload } from '@/utils/query'
+import { getDatasetInfo, getMethods, queryDataset, uploadDataset } from '@/service'
+import { DataFormats, UploadDatasetResponse, UploadDatasetResponseDetails } from '@/service/types'
+import { useMutation, useQuery } from '@tanstack/react-query'
+import { useRouter } from 'next/router'
+import { useState, ReactNode } from 'react'
+import {
+ Box,
+ Paper,
+ Typography,
+ Button,
+ Chip,
+ Alert,
+ LinearProgress,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ TextField,
+ Stack
+} from '@mui/material'
+import CloudUploadIcon from '@mui/icons-material/CloudUpload'
+
+type ActiveTab = 'download' | 'upload' | null
+
+function DatasetDetailPage() {
+ const router = useRouter()
+ const { layer, domain, dataset } = router.query
+ const version = router.query.version ? router.query.version : 0
+ const [activeTab, setActiveTab] = useState(null)
+ const [dataFormat, setDataFormat] = useState('csv')
+ const [showQuery, setShowQuery] = useState(false)
+ const [queryBody, setQueryBody] = useState({
+ select_columns: '',
+ filter: '',
+ group_by_columns: '',
+ aggregation_conditions: '',
+ limit: ''
+ })
+ const [noContentReturn, setNoContentReturn] = useState(false)
+ const [uploadFile, setUploadFile] = useState()
+ const [uploadDetails, setUploadDetails] = useState()
+ const [uploadDisable, setUploadDisable] = useState(false)
+
+ const { data: methods } = useQuery({
+ queryKey: ['methods'],
+ queryFn: getMethods
+ })
+
+ const {
+ isLoading,
+ data: info,
+ error
+ } = useQuery(
+ ['datasetInfo', layer, domain, dataset, version ? version : 0],
+ getDatasetInfo,
+ { enabled: !!layer && !!domain && !!dataset }
+ )
+
+ const { isLoading: isDownloading, mutate, error: downloadError } = useMutation<
+ Response,
+ Error,
+ { path: string; dataFormat: DataFormats; data: unknown }
+ >({
+ mutationFn: queryDataset,
+ onSuccess: async (response, { dataFormat: fmt }) => {
+ if (response.status === 200) {
+ setNoContentReturn(false)
+ triggerBlobDownload(await response.blob(), `${layer}_${domain}_${dataset}_${version}.${fmt}`)
+ } else if (response.status === 204) {
+ setNoContentReturn(true)
+ }
+ }
+ })
+
+ const { isLoading: isUploading, mutate: mutateUpload, error: uploadError } = useMutation<
+ UploadDatasetResponse,
+ Error,
+ { path: string; data: FormData }
+ >({
+ mutationFn: uploadDataset,
+ onMutate: () => setUploadDetails(undefined),
+ onSuccess: (data) => {
+ setUploadDetails(data.details)
+ setUploadDisable(true)
+ }
+ })
+
+ if (isLoading) {
+ return
+ }
+
+ if (error) {
+ return
+ }
+
+ if (!info) return null
+
+ const meta = info.metadata
+
+const tags = [
+ ...(meta.key_only_tags || []),
+ ...Object.entries(meta.key_value_tags || {}).map(([k, v]) => `${k}: ${v}`)
+ ]
+
+ const queryFields = [
+ { key: 'select_columns', label: 'Select Columns', placeholder: 'column1, avg(column2)' },
+ { key: 'filter', label: 'Filter', placeholder: 'column >= 10' },
+ { key: 'group_by_columns', label: 'Group by Columns', placeholder: 'column1, column3' },
+ { key: 'aggregation_conditions', label: 'Aggregation Conditions', placeholder: 'avg(column2) <= 15' },
+ { key: 'limit', label: 'Row Limit', placeholder: '30' }
+ ] as const
+
+ const stats: [string, string][] = [
+ ['Rows', meta.number_of_rows?.toLocaleString() ?? '—'],
+ ['Columns', meta.number_of_columns?.toLocaleString() ?? '—'],
+ ['Version', String(version)],
+ ['Last Updated', formatDate(meta.last_updated)],
+ ['Uploaded By', meta.last_uploaded_by || '—']
+ ]
+
+ return (
+
+
+ {methods?.can_download && (
+ setActiveTab(activeTab === 'download' ? null : 'download')}
+ >
+ Download
+
+ )}
+ {methods?.can_upload && (
+ setActiveTab(activeTab === 'upload' ? null : 'upload')}
+ >
+ Upload
+
+ )}
+ {methods?.can_create_schema && (
+ router.push(`/schema/edit/${layer}/${domain}/${dataset}?version=${version}`)}
+ >
+ Edit Schema
+
+ )}
+ {methods?.can_create_schema && (
+ router.push({
+ pathname: '/data/delete',
+ query: { layer: layer as string, domain: domain as string, dataset: dataset as string }
+ })}
+ >
+ Delete
+
+ )}
+
+
+ {activeTab === 'download' && methods?.can_download && (
+
+ mutate({
+ path: `${layer}/${domain}/${dataset}/query?version=${version}`,
+ dataFormat,
+ data: buildQueryPayload(queryBody)
+ })
+ }
+ >
+ {isDownloading ? 'Downloading…' : 'Download'}
+
+ }
+ >
+
+ Format:
+ {(['csv', 'json'] as DataFormats[]).map((fmt) => (
+ setDataFormat(fmt)}
+ variant={dataFormat === fmt ? 'filled' : 'outlined'}
+ color={dataFormat === fmt ? 'primary' : 'default'}
+ />
+ ))}
+
+
+ setShowQuery(!showQuery)} sx={{ mb: 1 }}>
+ {showQuery ? 'Hide query options' : 'Show query options (optional)'}
+
+
+ {showQuery && (
+
+
+ For further information on writing queries consult the{' '}
+
+ query writing guide
+
+
+
+ {queryFields.map(({ key, label, placeholder }) => (
+ setQueryBody({ ...queryBody, [key]: e.target.value })}
+ InputLabelProps={{ shrink: true }}
+ />
+ ))}
+
+
+ )}
+
+ {noContentReturn && (
+
+ No data returned for this query. Please ensure that data has been uploaded and the
+ query is not too restrictive.
+
+ )}
+
+ )}
+
+ {activeTab === 'upload' && methods?.can_upload && (
+ {
+ if (uploadFile) {
+ const formData = new FormData()
+ formData.append('file', uploadFile)
+ mutateUpload({
+ path: `${layer}/${domain}/${dataset}?version=${version}`,
+ data: formData
+ })
+ }
+ }}
+ >
+ {isUploading ? 'Uploading…' : 'Upload dataset'}
+
+ }
+ >
+ {!uploadDisable && (
+
+
+
+ Drag & drop your CSV file here
+
+
+ or click to browse — CSV only, max 100 MB
+
+ {uploadFile && (
+
+ {uploadFile.name}
+
+ )}
+
+ )}
+ setUploadFile(e.target.files?.[0])}
+ />
+
+ {uploadDetails && (
+
+
+
+ )}
+
+ )}
+
+
+
+ {dataset}
+
+ {meta.sensitivity && }
+
+
+ {layer} / {domain} / {dataset}
+
+ {meta.description && (
+ {meta.description}
+ )}
+
+
+
+ {stats.map(([label, value]) => (
+
+ {value}
+
+ {label}
+
+
+ ))}
+
+
+ {(meta.owners?.length || tags.length || meta.update_behaviour) ? (
+
+ {meta.update_behaviour && (
+
+
+ Update Behaviour
+
+ {meta.update_behaviour}
+
+ )}
+ {meta.owners && meta.owners.length > 0 && (
+
+
+ Owners
+
+
+ {meta.owners.map((o) => `${o.name} (${o.email})`).join(', ')}
+
+
+ )}
+ {tags.length > 0 && (
+
+
+ Tags
+
+
+ {tags.map((t) => )}
+
+
+ )}
+
+ ) : null}
+
+
+
+
+
+
+ Name
+ Data Type
+ Allows Null
+ Unique
+ Format
+ Max
+ Min
+
+
+
+ {info.columns.map((col, idx) => (
+
+ {col.name}
+ {col.data_type}
+ {col.allow_null ? 'Yes' : 'No'}
+ {col.unique ? 'Yes' : 'No'}
+ {col.format || '—'}
+ {col.statistics?.max || '—'}
+ {col.statistics?.min || '—'}
+
+ ))}
+
+
+
+
+
+ )
+}
+
+export default DatasetDetailPage
+
+DatasetDetailPage.getLayout = (page: ReactNode) => (
+ {page}
+)
diff --git a/frontend/src/pages/index.tsx b/frontend/src/pages/index.tsx
index 3b90ab62..771f0d44 100644
--- a/frontend/src/pages/index.tsx
+++ b/frontend/src/pages/index.tsx
@@ -1,171 +1,80 @@
-import { Typography, Grid, Stack, LinearProgress } from '@mui/material'
-import Image, { StaticImageData } from 'next/image'
import AccountLayout from '@/components/Layout/AccountLayout'
-import { Link, Row } from '@/components'
-import userIcon from '../../public/img/user_icon.png'
-import dataIcon from '../../public/img/data_icon.png'
-import schemaIcon from '../../public/img/schema_icon.png'
-import taskIcon from '../../public/img/task_icon.png'
-import { ComponentProps, ReactNode } from 'react'
+import DatasetSearchBar from '@/components/DatasetSearchBar/DatasetSearchBar'
import { useQuery } from '@tanstack/react-query'
-import { getMethods } from '@/service'
-
-function ManagementCard({
- iconImage,
- title,
- children,
- ...rest
-}: {
- iconImage: StaticImageData
- title: string
- children: ReactNode
-} & ComponentProps) {
- return (
-
-
-
-
- {title}
- {children}
-
-
-
- )
-}
+import { getMethods, getDatasetsUi } from '@/service'
+import { Dataset } from '@/service/types'
+import { ReactNode } from 'react'
+import { Box, Typography, LinearProgress } from '@mui/material'
function AccountIndexPage() {
const { data, isLoading } = useQuery({
queryKey: ['methods'],
- queryFn: getMethods,
- keepPreviousData: false,
- cacheTime: 0,
- refetchInterval: 0
+ queryFn: getMethods
})
- if (isLoading) {
- return
- }
-
- return (
-
-
- Welcome to rAPId
-
+ const canRead = data?.can_download || data?.can_search_catalog
+ const canWrite = data?.can_upload
-
- Getting Started
-
- With rAPId, users and clients can ingest, validate and query data via an API.
- The rAPId web application makes interactions with the API quicker and easier.
-
-
- To read more about the API or for technical architecture, see the links below.
- Otherwise, to get started choose an action from the menu below.
-
-
-
-
- View the API docs
-
-
- See the source code
-
-
- Contact
-
-
-
+ const { data: readDatasets } = useQuery(
+ ['datasetsList', 'READ'],
+ getDatasetsUi,
+ { enabled: !!canRead }
+ )
-
-
- {data.can_manage_users && (
-
- <>
-
- Create and modify different users and clients.
-
-
- Create User
-
-
- Modify User
-
- >
-
- )}
+ const { data: writeDatasets } = useQuery(
+ ['datasetsList', 'WRITE'],
+ getDatasetsUi,
+ { enabled: !!canWrite && !canRead }
+ )
- {(data.can_upload || data.can_download) && (
- <>
-
- <>
-
- Upload and download existing data files.
-
- {data.can_download && (
-
- Download Data
-
- )}
+ const datasets: Dataset[] = (readDatasets ?? writeDatasets ?? []) as Dataset[]
- {data.can_download && (
-
- Upload Data
-
- )}
- >
-
+ if (isLoading) {
+ return
+ }
- {data.can_create_schema && (
-
- <>
-
- Manually create new schemas from raw data.
-
-
- Create Schema
-
- >
-
- )}
+ return (
+
+
+
+ Welcome to rAPId
+
+
+
-
- <>
- View pending and complete api tasks.
-
- Tasks
-
- >
-
- >
- )}
-
-
-
+ {(data?.can_upload || data?.can_download) && }
+ {data?.can_create_schema && }
+ {data?.can_manage_users && }
+
)
}
export default AccountIndexPage
-AccountIndexPage.getLayout = (page) => (
- {page}
+AccountIndexPage.getLayout = (page: ReactNode) => (
+ {page}
)
diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx
index 754e17ec..337529e2 100644
--- a/frontend/src/pages/login.tsx
+++ b/frontend/src/pages/login.tsx
@@ -1,11 +1,12 @@
-import { Button, PublicLayout } from '@/components'
-import { Typography } from '@mui/material'
import { useState } from 'react'
import { useQueries } from '@tanstack/react-query'
import { useRouter } from 'next/router'
import { getAuthStatus, getLogin } from '@/service'
+import Image from 'next/image'
+import { Box, Typography, Button, LinearProgress } from '@mui/material'
+import { CenteredGradientPage } from '@/components'
-const IndexPage = () => {
+const LoginPage = () => {
const [authUrl, setAuthUrl] = useState('/login')
const router = useRouter()
@@ -20,9 +21,7 @@ const IndexPage = () => {
onSuccess: (data) => {
const { detail } = data
if (detail === 'success') {
- router.replace({
- pathname: '/'
- })
+ router.replace({ pathname: '/' })
}
}
},
@@ -40,51 +39,40 @@ const IndexPage = () => {
})
if (results[0].isLoading || results[1].isLoading) {
- return Loading...
+ return (
+
+
+
+ )
}
return (
- <>
+
+
+
+
+ Welcome back
+
+ Sign in to access your datasets and manage your data.
+
- Login
+ Sign in
- >
+
)
}
-export default IndexPage
-IndexPage.getLayout = (page) => (
-
-
- Project rAPId aims to create consistent, secure, interoperable data storage and
- sharing interfaces (APIs) that enable departments to discover, manage and share
- data and metadata amongst themselves.
-
-
-
- This will improve the government's use of data by making it more scalable,
- secure, and resilient, helping to match the rising demand for good-quality
- evidence in the design, delivery, and evaluation of public policy.
-
-
-
- The project aims to deliver a replicable template for simple data storage
- infrastructure in AWS, a RESTful API and custom frontend UI to ingest and share
- named, standardised datasets.
-
- >
- }
- >
- {page}
-
-)
+export default LoginPage
diff --git a/frontend/src/pages/schema/create/index.tsx b/frontend/src/pages/schema/create/index.tsx
index f2ca2e54..bf40d491 100644
--- a/frontend/src/pages/schema/create/index.tsx
+++ b/frontend/src/pages/schema/create/index.tsx
@@ -1,14 +1,6 @@
-import {
- Row,
- AccountLayout,
- Card,
- Select,
- TextField,
- Button,
- Alert,
- CreateSchema as CreateSchemaComponent
-} from '@/components'
+import { AccountLayout, FormCard } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
+import { CreateSchema as CreateSchemaComponent } from '@/components'
import {
generateSchema,
schemaGenerateSchema,
@@ -18,11 +10,21 @@ import {
import { getLayers } from '@/service/fetch'
import { GenerateSchemaResponse, SchemaGenerate } from '@/service/types'
import { zodResolver } from '@hookform/resolvers/zod'
-import { LinearProgress, Typography } from '@mui/material'
-import { useMutation } from '@tanstack/react-query'
-import { useState, useEffect } from 'react'
+import { useMutation, useQuery } from '@tanstack/react-query'
+import { useState, useEffect, ReactNode } from 'react'
import { useForm, Controller } from 'react-hook-form'
-import { useQuery } from '@tanstack/react-query'
+import {
+ Box,
+ Typography,
+ Button,
+ LinearProgress,
+ TextField,
+ Select,
+ FormControl,
+ InputLabel,
+ FormHelperText
+} from '@mui/material'
+import CloudUploadIcon from '@mui/icons-material/CloudUpload'
function CreateSchema() {
const [file, setFile] = useState()
@@ -44,7 +46,6 @@ function CreateSchema() {
}
})
- // Auto-select layer if only one option
useEffect(() => {
if (layersData?.length === 1) {
setValue('layer', layersData[0])
@@ -65,7 +66,7 @@ function CreateSchema() {
}
if (isLayersLoading) {
- return
+ return
}
if (layersError) {
@@ -73,153 +74,164 @@ function CreateSchema() {
}
return (
-
+
+ setFile(event.target.files[0])}
+ />
+
+
)
}
export default CreateSchema
-CreateSchema.getLayout = (page) => (
- {page}
+CreateSchema.getLayout = (page: ReactNode) => (
+ {page}
)
diff --git a/frontend/src/pages/schema/edit/[layer]/[domain]/[dataset].tsx b/frontend/src/pages/schema/edit/[layer]/[domain]/[dataset].tsx
new file mode 100644
index 00000000..8086d756
--- /dev/null
+++ b/frontend/src/pages/schema/edit/[layer]/[domain]/[dataset].tsx
@@ -0,0 +1,70 @@
+import AccountLayout from '@/components/Layout/AccountLayout'
+import ErrorCard from '@/components/ErrorCard/ErrorCard'
+import { CreateSchema as SchemaForm } from '@/components'
+import { getDatasetInfo } from '@/service'
+import { getLayers } from '@/service/fetch'
+import { GenerateSchemaResponse } from '@/service/types'
+import { useQuery } from '@tanstack/react-query'
+import { useRouter } from 'next/router'
+import { ReactNode } from 'react'
+import { LinearProgress } from '@mui/material'
+
+function EditSchema() {
+ const router = useRouter()
+ const { layer, domain, dataset } = router.query
+ const version = router.query.version ? router.query.version : 0
+
+ const {
+ isLoading: isLayersLoading,
+ data: layersData,
+ error: layersError
+ } = useQuery(['layers'], getLayers)
+
+ const {
+ isLoading: isInfoLoading,
+ data: infoData,
+ error: infoError
+ } = useQuery(
+ ['datasetInfo', layer, domain, dataset, version ? version : 0],
+ getDatasetInfo,
+ { enabled: !!layer && !!domain && !!dataset }
+ )
+
+ if (isLayersLoading || isInfoLoading) {
+ return
+ }
+
+ if (layersError) return
+ if (infoError) return
+ if (!infoData) return null
+
+ const schemaData: GenerateSchemaResponse = {
+ metadata: {
+ layer: layer as string,
+ domain: infoData.metadata.domain,
+ dataset: infoData.metadata.dataset,
+ sensitivity: infoData.metadata.sensitivity,
+ description: infoData.metadata.description,
+ update_behaviour: infoData.metadata.update_behaviour,
+ key_value_tags: infoData.metadata.key_value_tags || {},
+ key_only_tags: infoData.metadata.key_only_tags || [],
+ owners: infoData.metadata.owners || [{ name: '', email: '' }]
+ },
+ columns: infoData.columns.map((col) => ({
+ name: col.name,
+ partition_index: col.partition_index,
+ data_type: col.data_type,
+ allow_null: col.allow_null,
+ unique: col.unique,
+ format: col.format
+ }))
+ }
+
+ return
+}
+
+export default EditSchema
+
+EditSchema.getLayout = (page: ReactNode) => (
+ {page}
+)
diff --git a/frontend/src/pages/subject/create/index.tsx b/frontend/src/pages/subject/create/index.tsx
index 114d0bd6..fd595db0 100644
--- a/frontend/src/pages/subject/create/index.tsx
+++ b/frontend/src/pages/subject/create/index.tsx
@@ -1,7 +1,7 @@
-import { Card, Row, Button, TextField, Select, Alert } from '@/components'
-import AccountLayout from '@/components/Layout/AccountLayout'
+import { AccountLayout, FormCard } from '@/components'
+import ErrorCard from '@/components/ErrorCard/ErrorCard'
+import PermissionsTable from '@/components/PermissionsTable/PermissionsTable'
import { zodResolver } from '@hookform/resolvers/zod'
-import { Typography, LinearProgress } from '@mui/material'
import { Controller, useForm, useFieldArray } from 'react-hook-form'
import { z } from 'zod'
import { createClient, SubjectCreate } from '@/service'
@@ -15,8 +15,18 @@ import {
ClientCreateResponse,
UserCreateResponse
} from '@/service/types'
-import ErrorCard from '@/components/ErrorCard/ErrorCard'
-import PermissionsTable from '@/components/PermissionsTable/PermissionsTable'
+import { ReactNode } from 'react'
+import {
+ Box,
+ Typography,
+ Button,
+ LinearProgress,
+ TextField,
+ Select,
+ FormControl,
+ InputLabel,
+ FormHelperText
+} from '@mui/material'
const userType = ['User', 'Client']
@@ -68,176 +78,136 @@ function CreateUserPage() {
})
if (isPermissionsListLoading) {
- return
+ return
}
if (permissionsListError) {
return
}
- if (permissionsListData) {
- return (
-
- )
- }
- return <>>
+ (
+
+ )}
+ />
+
+
+
+
+ {isLoading ? 'Creating…' : 'Create subject'}
+
+ }
+ >
+
+
+
+ )
}
export default CreateUserPage
-CreateUserPage.getLayout = (page) => (
+CreateUserPage.getLayout = (page: ReactNode) => (
{page}
)
diff --git a/frontend/src/pages/subject/create/success.tsx b/frontend/src/pages/subject/create/success.tsx
index 12d73f83..ece59980 100644
--- a/frontend/src/pages/subject/create/success.tsx
+++ b/frontend/src/pages/subject/create/success.tsx
@@ -1,6 +1,5 @@
import { Card } from '@/components'
import AccountLayout from '@/components/Layout/AccountLayout'
-import { Typography } from '@mui/material'
import { useRouter } from 'next/router'
function SuccessPage() {
@@ -8,20 +7,14 @@ function SuccessPage() {
return (
-
- Success - Created
-
-
- You will only see this page once. Please make note of the details below.
-
+ Success - Created
+ You will only see this page once. Please make note of the details below.
- {Object.keys(router.query).map((key, index) => {
- return (
-
- {key}: {router.query[key]}
-
- )
- })}
+ {Object.keys(router.query).map((key, index) => (
+
+ {key}: {router.query[key]}
+
+ ))}
)
}
diff --git a/frontend/src/pages/subject/delete/index.tsx b/frontend/src/pages/subject/delete/index.tsx
index 536cbf5d..54518094 100644
--- a/frontend/src/pages/subject/delete/index.tsx
+++ b/frontend/src/pages/subject/delete/index.tsx
@@ -1,19 +1,25 @@
-import { AccountLayout, Card, Button, Row, Select, TextField } from '@/components'
+import { AccountLayout, FormCard } from '@/components'
+import ErrorCard from '@/components/ErrorCard/ErrorCard'
import { getSubjectsListUi } from '@/service'
-import {
- DialogActions,
- DialogContent,
- FormControl,
- LinearProgress,
- Typography
-} from '@mui/material'
+import { FilteredSubjectList } from '@/service/types'
import { useMutation, useQuery } from '@tanstack/react-query'
import { filterSubjectList } from '@/utils/subject'
-import { useEffect, useState } from 'react'
-import { FilteredSubjectList } from '@/service/types'
+import { useEffect, useState, ReactNode } from 'react'
import { deleteUser as deleteUserFn, deleteClient as deleteClientFn } from '@/service'
-import ErrorCard from '@/components/ErrorCard/ErrorCard'
-import Dialog from '@/components/Dialog/Dialog'
+import {
+ Box,
+ Typography,
+ Button,
+ LinearProgress,
+ TextField,
+ Select,
+ FormControl,
+ InputLabel,
+ Dialog,
+ DialogTitle,
+ DialogContent,
+ DialogActions
+} from '@mui/material'
function DeleteSubject() {
const [selectedSubjectId, setSelectedSubjectId] = useState('')
@@ -77,13 +83,12 @@ function DeleteSubject() {
)[0]
const { type, subject_id } = subject
if (type === 'CLIENT') deleteClient({ clientId: subject_id })
- if (type === 'USER')
- deleteUser({ userId: subject_id, username: subject.subject_name })
+ if (type === 'USER') deleteUser({ userId: subject_id, username: subject.subject_name })
}
const getCurrentSelectedSubjectName = () => {
return subjectsListData.filter((item) => item.subject_id === selectedSubjectId)[0]
- .subject_name
+ ?.subject_name ?? ''
}
if (subjectsListError) {
@@ -91,37 +96,36 @@ function DeleteSubject() {
}
if (isSubjectsListLoading || !selectedSubjectId) {
- return
+ return
}
return (
- {
- setIsConfirmDeleteDialogOpen(true)
- }}
- >
- Delete
-
- }
- >
-
- Delete an existing user or client.
-
-
- Select Subject
-
-
-
-
+
+ setIsConfirmDeleteDialogOpen(true)}
+ >
+ Delete
+
+ }
+ >
+
+ Delete an existing user or client.
+
+
+ Select a Client or User
setSelectedSubjectId(event.target.value as string)}
- inputProps={{ 'data-testid': 'field-user' }}
- native
+ inputProps={{ 'data-testid': 'field-user', id: 'field-user' }}
>
{filteredSubjectListData.ClientApps.map((item) => (
@@ -130,7 +134,6 @@ function DeleteSubject() {
))}
-
{filteredSubjectListData.Users.map((item) => (
@@ -140,53 +143,57 @@ function DeleteSubject() {
-
+
setIsConfirmDeleteDialogOpen(false)}
data-testid="delete-confirmation-dialog"
+ maxWidth="xs"
+ fullWidth
>
-
-
- This action cannot be undone. Please type in the name of the subject to
- confirm.
+ Confirm Delete
+
+
+ This action cannot be undone. Please type in the name of the subject to confirm.
-
+
{getCurrentSelectedSubjectName()}
setUserConfirmation(e.target.value)}
+ placeholder="Type subject name to confirm"
+ inputProps={{ 'data-testid': 'field-user-confirmation' }}
/>
- setIsConfirmDeleteDialogOpen(false)}>
+ setIsConfirmDeleteDialogOpen(false)}>
Cancel
- Delete
+ {isUserDeleting || isClientDeleting ? 'Deleting…' : 'Delete'}
-
+
)
}
export default DeleteSubject
-DeleteSubject.getLayout = (page) => (
+DeleteSubject.getLayout = (page: ReactNode) => (
{page}
)
diff --git a/frontend/src/pages/subject/index.tsx b/frontend/src/pages/subject/index.tsx
new file mode 100644
index 00000000..03d149d8
--- /dev/null
+++ b/frontend/src/pages/subject/index.tsx
@@ -0,0 +1,275 @@
+import AccountLayout from '@/components/Layout/AccountLayout'
+import ErrorCard from '@/components/ErrorCard/ErrorCard'
+import { sortByString } from '@/utils/sort'
+import { getSubjectsListUi, getSubjectPermissions } from '@/service'
+import { SubjectPermission } from '@/service/types'
+import { useQuery, useQueries } from '@tanstack/react-query'
+import { useRouter } from 'next/router'
+import Link from 'next/link'
+import { ReactNode, useState, useMemo } from 'react'
+import {
+ Box,
+ Paper,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ TableSortLabel,
+ TextField,
+ Select,
+ MenuItem,
+ Chip,
+ Button,
+ Typography,
+ LinearProgress,
+ InputAdornment
+} from '@mui/material'
+import SearchIcon from '@mui/icons-material/Search'
+import AddIcon from '@mui/icons-material/Add'
+
+type SubjectType = 'All' | 'USER' | 'CLIENT'
+
+type RoleFilter = 'All' | 'User Admin' | 'Data Admin' | 'Read/Write' | 'Read Only' | 'No Permissions'
+
+const ROLE_FILTERS: RoleFilter[] = ['All', 'User Admin', 'Data Admin', 'Read/Write', 'Read Only', 'No Permissions']
+
+// Roles in descending precedence — the first one the subject has wins.
+const ROLE_PRECEDENCE = ['USER_ADMIN', 'DATA_ADMIN', 'WRITE', 'READ'] as const
+
+function deriveRole(perms: SubjectPermission[] | undefined): RoleFilter {
+ if (!perms || perms.length === 0) return 'No Permissions'
+ const highest = ROLE_PRECEDENCE.find((type) => perms.some((p) => p.type === type))
+ switch (highest) {
+ case 'USER_ADMIN': return 'User Admin'
+ case 'DATA_ADMIN': return 'Data Admin'
+ case 'WRITE': return 'Read/Write'
+ case 'READ': return 'Read Only'
+ default: return 'No Permissions'
+ }
+}
+
+function UserAdminPage() {
+ const router = useRouter()
+ const [typeFilter, setTypeFilter] = useState('All')
+ const [roleFilter, setRoleFilter] = useState('All')
+ const [domainFilter, setDomainFilter] = useState('All')
+ const [search, setSearch] = useState('')
+ const [sortCol, setSortCol] = useState<'subject_name' | null>(null)
+ const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc')
+
+ const { isLoading, data, error } = useQuery(['subjectsList'], getSubjectsListUi, {
+ staleTime: Infinity,
+ keepPreviousData: true
+ })
+
+ const permissionQueries = useQueries({
+ queries: (data ?? []).map((s) => ({
+ queryKey: ['subjectPermissions', s.subject_id],
+ queryFn: getSubjectPermissions,
+ enabled: !!s.subject_id,
+ staleTime: Infinity,
+ keepPreviousData: true
+ }))
+ })
+
+ const permsBySubjectId = useMemo(() => {
+ if (!data) return {}
+ return Object.fromEntries(
+ data.map((s, i) => [s.subject_id, permissionQueries[i]?.data as SubjectPermission[] | undefined])
+ )
+ }, [data, permissionQueries])
+
+ const allDomains = useMemo(() => {
+ const domains = new Set()
+ Object.values(permsBySubjectId).forEach((perms) => {
+ perms?.forEach((p) => { if (p.domain) domains.add(p.domain) })
+ })
+ return ['All', ...Array.from(domains).sort()]
+ }, [permsBySubjectId])
+
+ const filtered = useMemo(() => {
+ if (!data) return []
+ const query = search.trim().toLowerCase()
+
+ const matchesType = (s: typeof data[number]) =>
+ typeFilter === 'All' || s.type === typeFilter
+
+ const matchesSearch = (s: typeof data[number]) =>
+ !query || String(s.subject_name ?? '').toLowerCase().includes(query)
+
+ const matchesRole = (perms: SubjectPermission[] | undefined) =>
+ roleFilter === 'All' || deriveRole(perms) === roleFilter
+
+ const matchesDomain = (perms: SubjectPermission[] | undefined) =>
+ domainFilter === 'All' || !!perms?.some((p) => p.domain === domainFilter)
+
+ return data.filter((s) => {
+ const perms = permsBySubjectId[s.subject_id as string]
+ return matchesType(s) && matchesSearch(s) && matchesRole(perms) && matchesDomain(perms)
+ })
+ }, [data, typeFilter, roleFilter, domainFilter, search, permsBySubjectId])
+
+ const sorted = useMemo(
+ () => sortByString(filtered, sortCol, sortDir),
+ [filtered, sortCol, sortDir]
+ )
+
+ function handleSort() {
+ if (sortCol === 'subject_name') {
+ setSortDir((d) => d === 'asc' ? 'desc' : 'asc')
+ } else {
+ setSortCol('subject_name')
+ setSortDir('asc')
+ }
+ }
+
+ if (isLoading) return
+ if (error) return
+
+ const typeFilters: SubjectType[] = ['All', 'USER', 'CLIENT']
+
+ return (
+
+ {/* Toolbar */}
+
+
+ setSearch(e.target.value)}
+ sx={{ flex: 1, minWidth: 200 }}
+ InputProps={{
+ startAdornment: ,
+ sx: { fontSize: 13 }
+ }}
+ />
+ }
+ component={Link}
+ href="/subject/create"
+ >
+ Create subject
+
+
+
+
+ {typeFilters.map((f) => (
+ setTypeFilter(f)}
+ />
+ ))}
+
+ setRoleFilter(e.target.value as RoleFilter)}
+ sx={{ minWidth: 130, fontSize: 13 }}
+ >
+ {ROLE_FILTERS.map((r) => (
+ {r === 'All' ? 'All Roles' : r}
+ ))}
+
+ setDomainFilter(e.target.value)}
+ sx={{ minWidth: 130, fontSize: 13 }}
+ >
+ {allDomains.map((d) => (
+ {d === 'All' ? 'All Domains' : d}
+ ))}
+
+
+
+
+ {/* Table */}
+
+
+
+
+
+
+ Name
+
+
+ Type
+ Role
+ Subject ID
+
+
+
+ {sorted.length > 0 ? (
+ sorted.map((subject, idx) => {
+ const perms = permsBySubjectId[subject.subject_id as string]
+ const role = deriveRole(perms)
+ const isLoadingPerms = !perms && permissionQueries[data.indexOf(subject)]?.isLoading
+ return (
+
+ router.push({
+ pathname: `/subject/modify/${subject.subject_id}`,
+ query: { name: subject.subject_name, type: subject.type }
+ })
+ }
+ sx={{ cursor: 'pointer' }}
+ >
+ {subject.subject_name}
+
+
+
+
+ {isLoadingPerms
+ ? …
+ : {role}
+ }
+
+ {subject.subject_id}
+
+ )
+ })
+ ) : (
+
+
+ {data?.length === 0
+ ? 'No subjects found. Create one to get started.'
+ : 'No subjects match the current filters.'}
+
+
+ )}
+
+
+
+
+ {/* Footer */}
+
+
+ {filtered.length} subject{filtered.length !== 1 ? 's' : ''}
+ {filtered.length !== data?.length ? ` (of ${data?.length})` : ''}
+
+
+
+ )
+}
+
+export default UserAdminPage
+
+UserAdminPage.getLayout = (page: ReactNode) => (
+ {page}
+)
diff --git a/frontend/src/pages/subject/modify/[subjectId].tsx b/frontend/src/pages/subject/modify/[subjectId].tsx
index f6d4de34..b8847530 100644
--- a/frontend/src/pages/subject/modify/[subjectId].tsx
+++ b/frontend/src/pages/subject/modify/[subjectId].tsx
@@ -1,60 +1,76 @@
-import { Button, Card } from '@/components'
+import { AccountLayout, FormCard } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
-import AccountLayout from '@/components/Layout/AccountLayout'
import {
getPermissionsListUi,
getSubjectPermissions,
- updateSubjectPermissions
+ updateSubjectPermissions,
+ deleteUser as deleteUserFn,
+ deleteClient as deleteClientFn
} from '@/service'
-import { Permission } from '@/service'
+import { Permission, ActionEnum, SensitivityEnum } from '@/service'
import { extractPermissionNames } from '@/service/permissions'
-import {
- UpdateSubjectPermissionsBody,
- UpdateSubjectPermissionsResponse
-} from '@/service/types'
-import { Alert, Typography, LinearProgress } from '@mui/material'
+import { UpdateSubjectPermissionsBody, UpdateSubjectPermissionsResponse } from '@/service/types'
import { useMutation, useQuery } from '@tanstack/react-query'
import { useRouter } from 'next/router'
-import { useEffect } from 'react'
+import { useEffect, useState, ReactNode } from 'react'
import { useForm, useFieldArray } from 'react-hook-form'
-import PermissionsTable from '@/components/PermissionsTable/PermissionsTable'
+import { cloneDeep } from 'lodash'
+import Link from 'next/link'
import { z } from 'zod'
+import {
+ Box,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Button,
+ Typography,
+ LinearProgress,
+ Alert,
+ Select,
+ MenuItem
+} from '@mui/material'
type PermissionType = z.infer
+type ActionType = z.infer
+type SensitivityType = z.infer
function SubjectModifyPage() {
const router = useRouter()
- const { subjectId, name } = router.query
+ const { subjectId, name, type: subjectType } = router.query
const { control, handleSubmit } = useForm()
+ const fieldArrayReturn = useFieldArray({ control, name: 'permissions' })
+ const { fields, append, remove } = fieldArrayReturn
- const fieldArrayReturn = useFieldArray({
- control,
- name: 'permissions'
- })
-
- const { append } = fieldArrayReturn
+ const [addType, setAddType] = useState('')
+ const [addLayer, setAddLayer] = useState('')
+ const [addSensitivity, setAddSensitivity] = useState('')
+ const [addDomain, setAddDomain] = useState('')
+ const [addError, setAddError] = useState('')
const {
- isLoading: isPermissionsListDataLoading,
+ isLoading: isPermissionsListLoading,
data: permissionsListData,
- error: permissionsListDataError
+ error: permissionsListError
} = useQuery(['permissionsList'], getPermissionsListUi)
const {
- isLoading: isSubjectPermissionsLoading,
- data: subjectPermissionsData,
- error: subjectPermissionsError
+ isLoading: isSubjectPermsLoading,
+ data: subjectPermsData,
+ error: subjectPermsError
} = useQuery(['subjectPermissions', subjectId], getSubjectPermissions)
useEffect(() => {
- if (subjectPermissionsData) {
- append(subjectPermissionsData)
+ if (subjectPermsData) {
+ fieldArrayReturn.append(subjectPermsData)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [subjectPermissionsData])
+ }, [subjectPermsData])
- const { isLoading, mutate, error } = useMutation<
+ const { isLoading: isSaving, mutate, error: saveError } = useMutation<
UpdateSubjectPermissionsResponse,
Error,
UpdateSubjectPermissionsBody
@@ -65,56 +81,275 @@ function SubjectModifyPage() {
}
})
- if (isPermissionsListDataLoading || isSubjectPermissionsLoading) {
- return
+ const { isLoading: isDeleting, mutate: doDelete, error: deleteError } = useMutation<
+ Response,
+ Error,
+ void
+ >({
+ mutationFn: async () => {
+ if (subjectType === 'CLIENT') {
+ return deleteClientFn({ clientId: subjectId as string })
+ }
+ return deleteUserFn({ userId: subjectId as string, username: name as string })
+ },
+ onSuccess: () => {
+ router.push('/subject')
+ }
+ })
+
+ if (isPermissionsListLoading || isSubjectPermsLoading) {
+ return
+ }
+
+ if (permissionsListError || subjectPermsError) {
+ return
}
- if (permissionsListDataError || subjectPermissionsError) {
- return (
-
- )
+ let filteredPerms = cloneDeep(permissionsListData)
+ try {
+ ;(fields as unknown as PermissionType[]).forEach((perm) => {
+ filteredPerms = removePermOption(perm, filteredPerms)
+ })
+ } catch {
+ // tolerate conflicts gracefully
+ }
+
+ const availableTypes = Object.keys(filteredPerms ?? {})
+ const availableLayers = addType && filteredPerms?.[addType]
+ ? Object.keys(filteredPerms[addType] as object)
+ : []
+ const availableSensitivities = addType && addLayer && (filteredPerms?.[addType] as Record)?.[addLayer]
+ ? Object.keys((filteredPerms[addType] as Record>)[addLayer])
+ : []
+ const availableDomains = addType && addLayer && addSensitivity === 'PROTECTED' &&
+ (filteredPerms?.[addType] as Record>>)?.[addLayer]?.['PROTECTED']
+ ? Object.keys((filteredPerms[addType] as Record>>)[addLayer]['PROTECTED'])
+ : []
+
+ const isAdminType = addType === 'DATA_ADMIN' || addType === 'USER_ADMIN'
+ const canAdd = addType !== '' && (isAdminType || (addLayer && addSensitivity && (addSensitivity !== 'PROTECTED' || addDomain)))
+
+ function handleAdd() {
+ setAddError('')
+ if (!canAdd) {
+ setAddError('Please fill in all required fields.')
+ return
+ }
+ const perm: PermissionType = isAdminType
+ ? { type: addType as 'DATA_ADMIN' | 'USER_ADMIN', layer: undefined, sensitivity: undefined, domain: undefined }
+ : { type: addType as 'READ' | 'WRITE', layer: addLayer, sensitivity: addSensitivity as SensitivityType, domain: addSensitivity === 'PROTECTED' ? addDomain : undefined }
+ append(perm)
+ setAddType('')
+ setAddLayer('')
+ setAddSensitivity('')
+ setAddDomain('')
}
return (
-
+
+
+
)
}
+function removePermOption(permission: PermissionType, permsList: Record) {
+ if (!permsList) return permsList
+ const { type, layer, sensitivity, domain } = permission as {
+ type: string; layer?: string; sensitivity?: string; domain?: string
+ }
+ const typeList = permsList[type] as Record
+
+ if (!layer) {
+ delete permsList[type]
+ return permsList
+ }
+
+ const layerList = typeList?.[layer] as Record
+ if (!sensitivity) return permsList
+ const sensitivityList = layerList?.[sensitivity] as Record
+
+ if (domain) {
+ if (sensitivityList && domain in sensitivityList) delete sensitivityList[domain]
+ if (sensitivityList && !Object.keys(sensitivityList).length) delete layerList[sensitivity]
+ if (layerList && !Object.keys(layerList).length) delete typeList[layer]
+ } else {
+ if (layerList && sensitivity in layerList) delete layerList[sensitivity]
+ if (layerList && (!Object.keys(layerList).length || sensitivity === 'ALL')) {
+ delete typeList[layer]
+ if (typeList && (!Object.keys(typeList).length || layer === 'ALL')) delete permsList[type]
+ }
+ }
+
+ return permsList
+}
+
export default SubjectModifyPage
-SubjectModifyPage.getLayout = (page) => (
- {page}
+SubjectModifyPage.getLayout = (page: ReactNode) => (
+ {page}
)
diff --git a/frontend/src/pages/subject/modify/index.tsx b/frontend/src/pages/subject/modify/index.tsx
index 7fbe88ea..7505eb86 100644
--- a/frontend/src/pages/subject/modify/index.tsx
+++ b/frontend/src/pages/subject/modify/index.tsx
@@ -1,108 +1,108 @@
-import { Card, Row, Button, Select } from '@/components'
+import { AccountLayout, FormCard } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
-import AccountLayout from '@/components/Layout/AccountLayout'
import { getSubjectsListUi } from '@/service'
-import { FilteredSubjectList } from '@/service/types'
-import { FormControl, Typography, LinearProgress } from '@mui/material'
import { useQuery } from '@tanstack/react-query'
import { useRouter } from 'next/router'
-import { useEffect, useState } from 'react'
+import { useState, useMemo, useEffect, ReactNode } from 'react'
import { filterSubjectList } from '@/utils/subject'
+import {
+ Box,
+ Button,
+ LinearProgress,
+ Select,
+ FormControl,
+ InputLabel
+} from '@mui/material'
function SubjectModifyPage() {
const router = useRouter()
const [selectedSubjectId, setSelectedSubjectId] = useState('')
- const [filteredSubjectListData, setFilteredSubjectListData] =
- useState({ ClientApps: [], Users: [] })
- const {
- isLoading: isSubjectsListLoading,
- data: subjectsListData,
- error: subjectsListError
- } = useQuery(['subjectsList'], getSubjectsListUi)
+ const { isLoading, data: subjectsListData, error } = useQuery(
+ ['subjectsList'],
+ getSubjectsListUi
+ )
- useEffect(() => {
- if (subjectsListData) {
- const users = filterSubjectList(subjectsListData, 'USER')
- const clients = filterSubjectList(subjectsListData, 'CLIENT')
+ const users = useMemo(
+ () => (subjectsListData ? filterSubjectList(subjectsListData, 'USER') : []),
+ [subjectsListData]
+ )
- // eslint-disable-next-line react-hooks/set-state-in-effect
- setFilteredSubjectListData({ ClientApps: clients, Users: users })
- setSelectedSubjectId(clients[0].subjectId)
- }
- }, [subjectsListData])
+ const clients = useMemo(
+ () => (subjectsListData ? filterSubjectList(subjectsListData, 'CLIENT') : []),
+ [subjectsListData]
+ )
- if (isSubjectsListLoading) {
- return
- }
+ useEffect(() => {
+ if (!selectedSubjectId && (users.length > 0 || clients.length > 0)) {
+ setSelectedSubjectId(users[0]?.subjectId ?? clients[0]?.subjectId ?? '')
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [users, clients])
- if (subjectsListError) {
- return
- }
+ if (isLoading) return
+ if (error) return
return (
- {
- const subject = subjectsListData.filter(
- (item) => item.subject_id === selectedSubjectId
- )[0]
- router.push({
- pathname: `/subject/modify/${selectedSubjectId}`,
- query: {
- name: subject.subject_name
- }
- })
- }}
- >
- Next
-
- }
- >
-
- Modify the permissions a user or client can have. Select the user or client from
- the list below and update their permissions on the next screen.
-
-
-
- Select Subject
-
-
-
-
+
+ {
+ const subject = subjectsListData.find(
+ (item) => item.subject_id === selectedSubjectId
+ )
+ router.push({
+ pathname: `/subject/modify/${selectedSubjectId}`,
+ query: { name: subject?.subject_name }
+ })
+ }}
+ >
+ Next →
+
+ }
+ >
+
+ Subject
setSelectedSubjectId(event.target.value as string)}
- inputProps={{ 'data-testid': 'field-user' }}
native
+ label="Subject"
+ notched
+ value={selectedSubjectId}
+ onChange={(e) => setSelectedSubjectId(e.target.value as string)}
+ inputProps={{ 'data-testid': 'field-user', id: 'field-user' }}
>
-
- {filteredSubjectListData.ClientApps.map((item) => (
-
- {item.subjectName}
-
- ))}
-
-
-
- {filteredSubjectListData.Users.map((item) => (
-
- {item.subjectName}
-
- ))}
-
+ {users.length > 0 && (
+
+ {users.map((item) => (
+
+ {item.subjectName}
+
+ ))}
+
+ )}
+ {clients.length > 0 && (
+
+ {clients.map((item) => (
+
+ {item.subjectName}
+
+ ))}
+
+ )}
-
-
+
+
)
}
export default SubjectModifyPage
-SubjectModifyPage.getLayout = (page) => (
- {page}
+SubjectModifyPage.getLayout = (page: ReactNode) => (
+ {page}
)
diff --git a/frontend/src/pages/subject/modify/success/[subjectId].tsx b/frontend/src/pages/subject/modify/success/[subjectId].tsx
index 855f07b1..5633c0b1 100644
--- a/frontend/src/pages/subject/modify/success/[subjectId].tsx
+++ b/frontend/src/pages/subject/modify/success/[subjectId].tsx
@@ -1,9 +1,9 @@
-import { AccountLayout } from '@/components'
+import { AccountLayout, Card } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
import { getSubjectPermissions } from '@/service'
-import { Card, Stack, Typography, LinearProgress } from '@mui/material'
import { useQuery } from '@tanstack/react-query'
import { useRouter } from 'next/router'
+import { LinearProgress } from '@mui/material'
function SubjectModifyPageSuccess() {
const router = useRouter()
@@ -18,7 +18,7 @@ function SubjectModifyPageSuccess() {
})
if (isSubjectPermissionsLoading) {
- return
+ return
}
if (subjectPermissionsError) {
@@ -27,16 +27,14 @@ function SubjectModifyPageSuccess() {
return (
-
- Success
-
- Permissions modified for {name}
+ Success
+ Permissions modified for {name}
-
+
{subjectPermissionsData.map((item) => (
- {item.name}
+ {item.id}
))}
-
+
)
}
diff --git a/frontend/src/pages/tasks/[jobId].tsx b/frontend/src/pages/tasks/[jobId].tsx
index 5efeb22b..740406f8 100644
--- a/frontend/src/pages/tasks/[jobId].tsx
+++ b/frontend/src/pages/tasks/[jobId].tsx
@@ -1,73 +1,220 @@
+import { AccountLayout, FormCard } from '@/components'
import ErrorCard from '@/components/ErrorCard/ErrorCard'
-import AccountLayout from '@/components/Layout/AccountLayout'
-import SimpleTable from '@/components/SimpleTable/SimpleTable'
-import { asVerticalTableList } from '@/utils'
+import StatusChip from '@/components/Chip/StatusChip'
+import { formatTs } from '@/utils/date'
import { getJob } from '@/service'
-import { Card, Typography, LinearProgress } from '@mui/material'
import { useQuery } from '@tanstack/react-query'
import { useRouter } from 'next/router'
+import { ReactNode } from 'react'
+import Link from 'next/link'
+import {
+ Box,
+ Paper,
+ Typography,
+ Button,
+ Chip,
+ Alert,
+ AlertTitle,
+ LinearProgress,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableRow,
+ Stack
+} from '@mui/material'
-function GetJob() {
- const router = useRouter()
- const { jobId } = router.query
- const { isLoading, data, error } = useQuery(['getJob', jobId], getJob)
+type ParsedError = {
+ title: string
+ detail: string
+}
- if (isLoading) {
- return
+function parseError(raw: string): ParsedError {
+ const colMismatch = raw.match(/Expected columns:\s*(\[[\s\S]*?\]),\s*received:\s*(\[[\s\S]*?\])/)
+ if (colMismatch) {
+ return {
+ title: 'Column mismatch — your file does not match the schema',
+ detail: `The schema expects columns ${colMismatch[1]} but your file contains ${colMismatch[2]}. Check that all required columns are present and no extra columns have been added.`
+ }
}
- if (error) {
- return
+ const dateFormat = raw.match(/Column \[(.+?)\] does not match specified date format/)
+ if (dateFormat) {
+ return {
+ title: `Invalid date format in column "${dateFormat[1]}"`,
+ detail: `At least one value in the "${dateFormat[1]}" column does not match the date format required by the schema. Check that all dates in this column are consistently formatted.`
+ }
}
- const renderErrors = () => {
- if (data.errors) {
- if ((data.errors as string[]).length) {
- return (
- <>
-
- Errors
-
- {(data.errors as string[]).map((error, index) => (
-
- {error}
-
- ))}
- >
- )
- }
+ const dataType = raw.match(/Column \[(.+?)\] has an incorrect data type\. Expected (.+?), received (.+)/)
+ if (dataType) {
+ return {
+ title: `Wrong data type in column "${dataType[1]}"`,
+ detail: `The schema expects "${dataType[1]}" to contain ${dataType[2]} values, but your file contains ${dataType[3]} values. Check that the column contains the correct type of data.`
}
- return null
}
+ const partition = raw.match(/Partition column \[(.+?)\] has values with illegal characters/)
+ if (partition) {
+ return {
+ title: `Illegal character in partition column "${partition[1]}"`,
+ detail: `Values in the "${partition[1]}" column contain a "/" character, which is not allowed in partition columns. Remove or replace any forward slashes in this column.`
+ }
+ }
+
+ if (/dataset has no rows/i.test(raw)) {
+ return {
+ title: 'File contains no data rows',
+ detail: 'Your file appears to be empty or contains only a header row. Make sure your file has at least one data row before uploading.'
+ }
+ }
+
+ const nullable = raw.match(/column\s*['""]?(.+?)['""]?\s+.*?null/i)
+ if (nullable && /null/i.test(raw)) {
+ const col = nullable[1].replace(/['"]/g, '').trim()
+ return {
+ title: `Missing values found in column "${col}"`,
+ detail: `The "${col}" column has empty or null values, but the schema requires this column to always have a value. Fill in any blank cells in this column before re-uploading.`
+ }
+ }
+
+ if (/unique/i.test(raw)) {
+ const colMatch = raw.match(/column\s+['""]?(.+?)['""]?[\s,]/i)
+ const col = colMatch ? colMatch[1].replace(/['"]/g, '').trim() : 'a column'
+ return {
+ title: `Duplicate values found in column "${col}"`,
+ detail: `The "${col}" column must contain unique values, but duplicate entries were found. Remove duplicates before re-uploading.`
+ }
+ }
+
+ return {
+ title: 'Validation error',
+ detail: raw
+ }
+}
+
+function GetJob() {
+ const router = useRouter()
+ const { jobId } = router.query
+ const { isLoading, data, error } = useQuery(['getJob', jobId], getJob)
+
+ if (isLoading) return
+ if (error) return
+
+ const errors: string[] = Array.isArray(data.errors)
+ ? (data.errors as string[])
+ : data.errors
+ ? [String(data.errors)]
+ : []
+
+ const parsedErrors = errors.map(parseError)
+ const hasFailed = data.status === 'FAILED'
+ const createdAtStr = formatTs(data.createdat as number | string | undefined, 'long')
+
+ const metaRows: [string, ReactNode][] = [
+ ['Job ID', {data.job_id as string} ],
+ ['Type', data.type as string],
+ ...(data.filename ? [['File', {data.filename as string} ] as [string, ReactNode]] : []),
+ ['Dataset', `${data.domain} / ${data.dataset}`],
+ ['Layer', data.layer as string],
+ ['Version', String(data.version)],
+ ...(createdAtStr ? [['Started', createdAtStr] as [string, ReactNode]] : []),
+ ]
+
return (
-
-
- Job Detail
-
-
- Status - {data.status}
- ID - {data.job_id}
-
-
-
- {renderErrors()}
-
+
+ }
+ bodySx={{ p: 0 }}
+ >
+
+
+
+ {metaRows.map(([k, v]) => (
+
+
+ {k}
+
+ {v}
+
+ ))}
+
+
+
+
+
+ {hasFailed && parsedErrors.length > 0 && (
+
+ Failure details
+
+ No data was written. Fix the issues below, then re-upload.
+
+
+ }
+ headerAction={
+
+ }
+ >
+
+
+ {parsedErrors.map((e, i) => (
+
+ {e.title}
+ {e.detail}
+
+ ))}
+
+
+
+
+ What would you like to do?
+
+
+
+ Fix my file
+
+ Update the values in your file to match what the schema expects, then re-upload.
+
+
+ ↑ Upload again
+
+
+
+ Update the schema
+
+ If your file is correct, delete the existing dataset first, then create a new schema and re-upload. Requires Data Admin permissions.
+
+
+ Go to Catalog →
+
+
+
+
+
+
+ )}
+
+ {!hasFailed && (
+
+
+ ← Back to Jobs
+
+
+ )}
+
)
}
export default GetJob
-GetJob.getLayout = (page) => {page}
+GetJob.getLayout = (page: ReactNode) => (
+ {page}
+)
diff --git a/frontend/src/pages/tasks/index.tsx b/frontend/src/pages/tasks/index.tsx
index 09577ec9..02476074 100644
--- a/frontend/src/pages/tasks/index.tsx
+++ b/frontend/src/pages/tasks/index.tsx
@@ -1,83 +1,128 @@
-import { Card, Link, SimpleTable, AccountLayout } from '@/components'
+import AccountLayout from '@/components/Layout/AccountLayout'
+import ErrorCard from '@/components/ErrorCard/ErrorCard'
+import StatusChip from '@/components/Chip/StatusChip'
+import { formatTs } from '@/utils/date'
import { getAllJobs } from '@/service'
-import { Typography, LinearProgress } from '@mui/material'
import { useQuery } from '@tanstack/react-query'
-import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'
-import CancelIcon from '@mui/icons-material/Cancel'
-import QueryBuilderIcon from '@mui/icons-material/QueryBuilder'
-import ErrorCard from '@/components/ErrorCard/ErrorCard'
+import { ReactNode, useState, useMemo } from 'react'
+import {
+ Box,
+ Paper,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Chip,
+ Typography,
+ LinearProgress
+} from '@mui/material'
+import Link from 'next/link'
-function getStatusSymbol(status: string) {
- if (status === 'SUCCESS') return
- else if (status === 'IN PROGRESS') return
- else if (status === 'FAILED') return
-}
+
+type TypeFilter = 'All' | 'UPLOAD' | 'QUERY'
function StatusPage() {
const { isLoading, data, error } = useQuery(['jobs'], getAllJobs)
+ const [typeFilter, setTypeFilter] = useState('All')
- if (isLoading) {
- return
- }
+ const typeFilters: TypeFilter[] = ['All', 'UPLOAD', 'QUERY']
- if (error) {
- return
- }
+ const filtered = useMemo(() => {
+ if (!data) return []
+ if (typeFilter === 'All') return data
+ return data.filter((job) => (job.type as string)?.toUpperCase() === typeFilter)
+ }, [data, typeFilter])
- return (
-
-
- View all the tracked asynchronous processing jobs and the status of each job.
- Press the desired job id to get greater details on it's run.
-
+ const hasCreatedAt = useMemo(
+ () => filtered.some((job) => job.createdat != null),
+ [filtered]
+ )
+
+ if (isLoading) return
+ if (error) return
-
- Jobs
-
+ return (
+
+ {/* Toolbar */}
+
+ {typeFilters.map((f) => (
+ setTypeFilter(f)}
+ />
+ ))}
+
- {
- return [
- { children: <>{job.type}> },
- { children: <>{job.layer}> },
- { children: <>{job.domain}> },
- { children: <>{job.dataset}> },
- { children: <>{job.version}> },
- { children: getStatusSymbol(job.status as string) },
- { children: <>{job.step}> },
- {
- children: (
-
- {job.job_id}
-
- )
- },
- {
- children:
- job.status === 'FAILED' ? (
- Failure Details
- ) : (
- <>>
+ {/* Table */}
+
+
+
+
+ Job ID
+ Type
+ Layer
+ Domain
+ Dataset
+ Version
+ Status
+ Step
+ {hasCreatedAt && Created At }
+
+
+
+ {filtered.length === 0 ? (
+
+
+ No {typeFilter !== 'All' ? typeFilter.toLowerCase() : ''} jobs found.
+
+
+ ) : (
+ filtered.map((job, idx) => {
+ const createdAtStr = formatTs(job.createdat as number | string | undefined)
+ return (
+
+
+
+ {job.job_id}
+
+
+ {job.type}
+ {job.layer}
+ {job.domain}
+ {job.dataset}
+ {job.version}
+
+ {job.step}
+ {hasCreatedAt && (
+ {createdAtStr ?? '—'}
+ )}
+
)
- }
- ]
- })}
- headers={[
- { children: 'Type' },
- { children: 'Layer' },
- { children: 'Domain' },
- { children: 'Dataset' },
- { children: 'Version' },
- { children: 'Status' },
- { children: 'Step' },
- { children: 'Job ID' },
- { children: '' }
- ]}
- />
-
+ })
+ )}
+
+
+
+
+ {/* Footer */}
+
+
+ {filtered.length} job{filtered.length !== 1 ? 's' : ''}
+ {typeFilter !== 'All' ? ` (${typeFilter.toLowerCase()})` : ''}
+
+
+
)
}
export default StatusPage
-StatusPage.getLayout = (page) => {page}
+StatusPage.getLayout = (page: ReactNode) => (
+ {page}
+)
diff --git a/frontend/src/service/constants.ts b/frontend/src/service/constants.ts
index c2703ea9..5251a367 100644
--- a/frontend/src/service/constants.ts
+++ b/frontend/src/service/constants.ts
@@ -42,9 +42,9 @@ export const dataDeleteMethod = [
]
export const schemaManagementMethods = [
- { text: 'Schema Management' },
+ { text: 'Dataset Management' },
{
- text: 'Create Schema',
+ text: 'Add New Dataset',
href: '/schema/create/',
icon: 'AppsAdd'
}
diff --git a/frontend/src/service/fetch.ts b/frontend/src/service/fetch.ts
index 94b3142a..894bc403 100644
--- a/frontend/src/service/fetch.ts
+++ b/frontend/src/service/fetch.ts
@@ -204,6 +204,16 @@ export const createSchema = async (
return res.json()
}
+export const updateSchema = async (
+ data: GenerateSchemaResponse
+): Promise => {
+ const res = await api(`/api/schema`, {
+ method: 'PUT',
+ body: JSON.stringify(data)
+ })
+ return res.json()
+}
+
export const deleteClient = async ({ clientId }: { clientId: string }) => {
const res = await api(`/api/client/${clientId}`, {
method: 'DELETE'
diff --git a/frontend/src/service/types.ts b/frontend/src/service/types.ts
index 9cef67cf..0cf7c051 100644
--- a/frontend/src/service/types.ts
+++ b/frontend/src/service/types.ts
@@ -132,6 +132,7 @@ export type AllJobsResponse = JobResponse[]
export type MethodsResponse = {
message: string | null
+ username?: string | null
can_manage_users?: boolean
can_upload?: boolean
can_download?: boolean
@@ -164,10 +165,13 @@ export type Dataset = {
domain: string
dataset: string
version: number
+ sensitivity?: string
+ last_updated?: string
+ last_uploaded_by?: string
}
export type SubjectPermission = {
- name: string
+ id: string
type: string
layer: string | undefined
sensitivity: string | undefined
diff --git a/frontend/src/style/theme.ts b/frontend/src/style/theme.ts
index eba39253..a59687fe 100644
--- a/frontend/src/style/theme.ts
+++ b/frontend/src/style/theme.ts
@@ -18,7 +18,8 @@ const colors: Colors = {
}
const fonts = {
- default: ['Khula', 'Poppins', 'sans-serif']
+ default: ['Poppins', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'sans-serif'],
+ mono: ['DM Mono', 'monospace']
}
const theme = createTheme({
@@ -31,10 +32,32 @@ const theme = createTheme({
dark: colors.pink3
},
secondary: {
- main: colors.grey3,
- light: colors.grey1,
- dark: colors.grey4
- }
+ main: '#1e3a5f',
+ light: '#2a4a72',
+ dark: '#162d4a'
+ },
+ error: {
+ main: '#ef4444'
+ },
+ warning: {
+ main: '#f59e0b'
+ },
+ success: {
+ main: '#10b981'
+ },
+ info: {
+ main: '#3b82f6'
+ },
+ background: {
+ default: '#eef0f3',
+ paper: '#ffffff'
+ },
+ text: {
+ primary: '#111827',
+ secondary: '#4b5563',
+ disabled: '#9ca3af'
+ },
+ divider: '#e5e7eb'
},
typography: {
fontFamily: fonts.default.join(','),
@@ -69,7 +92,7 @@ const theme = createTheme({
body1: {
fontWeight: 500,
fontSize: 14,
- lineHeight: '150%;',
+ lineHeight: '150%',
letterSpacing: '0.15px',
'&.MuiTypography-gutterBottom': {
marginBottom: 10
@@ -79,7 +102,7 @@ const theme = createTheme({
fontSize: 12,
fontWeight: 500,
color: colors.grey4,
- lineHeight: '150%;',
+ lineHeight: '150%',
letterSpacing: '0.15px',
'&.MuiTypography-gutterBottom': {
marginBottom: 10
@@ -133,18 +156,65 @@ const theme = createTheme({
}
`
},
+ MuiTableHead: {
+ styleOverrides: {
+ root: {
+ backgroundColor: '#fafafa',
+ '& .MuiTableCell-head': {
+ fontSize: 10,
+ fontWeight: 600,
+ letterSpacing: '0.07em',
+ textTransform: 'uppercase',
+ color: '#9ca3af',
+ padding: '10px 16px',
+ borderBottom: '1px solid #f3f4f6',
+ whiteSpace: 'nowrap'
+ }
+ }
+ }
+ },
+ MuiTableCell: {
+ styleOverrides: {
+ body: {
+ fontSize: 13,
+ padding: '11px 16px',
+ borderBottom: '1px solid #f9fafb',
+ color: '#111827'
+ }
+ }
+ },
+ MuiTableRow: {
+ styleOverrides: {
+ root: {
+ '&.MuiTableRow-hover:hover': {
+ backgroundColor: '#fafafa',
+ cursor: 'pointer'
+ }
+ }
+ }
+ },
+ MuiChip: {
+ styleOverrides: {
+ root: {
+ fontWeight: 500
+ },
+ sizeSmall: {
+ fontSize: 11,
+ height: 28,
+ borderRadius: 20,
+ paddingLeft: 4,
+ paddingRight: 4
+ }
+ }
+ },
MuiListItemButton: {
styleOverrides: {
root: {
'&.Mui-selected': {
'&:hover': {
- backgroundColor: '#f8f8f8'
+ backgroundColor: 'rgba(255,255,255,0.12)'
},
- backgroundColor: '#f8f8f8',
-
- '.MuiListItemText-root': {
- fontWeight: 900
- }
+ backgroundColor: 'rgba(255,255,255,0.08)'
},
'&.Mui-disabled': {
opacity: 1
@@ -161,8 +231,7 @@ const theme = createTheme({
MuiInputBase: {
styleOverrides: {
root: {
- fontSize: 16,
- // To stop chrome autofill changing background color
+ fontSize: 14,
'& input': {
'&:-webkit-autofill': {
transition:
@@ -183,7 +252,7 @@ const theme = createTheme({
MuiMenuItem: {
styleOverrides: {
root: {
- fontSize: 16
+ fontSize: 14
}
}
},
@@ -191,7 +260,7 @@ const theme = createTheme({
styleOverrides: {
root: {
textTransform: 'none',
- backgrondColor: colors.blue1
+ fontWeight: 600
}
}
},
@@ -206,7 +275,9 @@ const theme = createTheme({
MuiFormLabel: {
styleOverrides: {
root: {
- fontSize: 16
+ fontSize: 13,
+ fontWeight: 600,
+ color: '#374151'
}
}
},
@@ -214,7 +285,7 @@ const theme = createTheme({
styleOverrides: {
root: {
'.MuiFormControlLabel-label': {
- fontSize: 16
+ fontSize: 14
}
}
}
@@ -230,22 +301,26 @@ const theme = createTheme({
MuiCard: {
styleOverrides: {
root: {
- boxShadow: '0px 4px 12px rgba(0, 0, 0, 0.15)',
- padding: 20
+ boxShadow: '0px 1px 3px rgba(0,0,0,0.06), 0px 1px 2px rgba(0,0,0,0.04)',
+ padding: 0
}
}
},
MuiPaper: {
styleOverrides: {
root: {
- boxShadow: '0px 4px 12px rgba(0, 0, 0, 0.15)'
+ boxShadow: '0px 1px 3px rgba(0,0,0,0.06), 0px 1px 2px rgba(0,0,0,0.04)'
+ },
+ outlined: {
+ boxShadow: 'none'
}
}
},
MuiAlert: {
styleOverrides: {
root: {
- boxShadow: 'none'
+ boxShadow: 'none',
+ fontSize: 13
}
}
},
@@ -266,6 +341,13 @@ const theme = createTheme({
}
}
}
+ },
+ MuiLinearProgress: {
+ styleOverrides: {
+ root: {
+ borderRadius: 4
+ }
+ }
}
}
})
diff --git a/frontend/src/utils/date.ts b/frontend/src/utils/date.ts
new file mode 100644
index 00000000..77283113
--- /dev/null
+++ b/frontend/src/utils/date.ts
@@ -0,0 +1,25 @@
+// Formats an ISO-style date string (or anything Date can parse) as
+// "23 Aug 2026 14:05". Falls back to the raw string if unparseable, '—' if absent.
+export function formatDate(raw: string | undefined): string {
+ if (!raw) return '—'
+ const d = new Date(raw)
+ if (isNaN(d.getTime())) return raw
+ return d.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' })
+ + ' ' + d.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' })
+}
+
+// Formats a unix timestamp (seconds, number or numeric string) for display.
+// Returns null when the input is missing or unparseable.
+export function formatTs(
+ ts: number | string | undefined,
+ style: 'short' | 'long' = 'short'
+): string | null {
+ if (!ts) return null
+ const seconds = typeof ts === 'string' ? parseInt(ts, 10) : ts
+ if (!seconds || isNaN(seconds)) return null
+ const options: Intl.DateTimeFormatOptions =
+ style === 'long'
+ ? { day: 'numeric', month: 'long', year: 'numeric', hour: '2-digit', minute: '2-digit' }
+ : { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit' }
+ return new Date(seconds * 1000).toLocaleString('en-GB', options)
+}
diff --git a/frontend/src/utils/download.ts b/frontend/src/utils/download.ts
new file mode 100644
index 00000000..ebd76fd7
--- /dev/null
+++ b/frontend/src/utils/download.ts
@@ -0,0 +1,11 @@
+// Triggers a browser download of a Blob with the given filename.
+export function triggerBlobDownload(blob: Blob, filename: string): void {
+ const url = window.URL.createObjectURL(blob)
+ const a = document.createElement('a')
+ a.style.display = 'none'
+ a.href = url
+ a.download = filename
+ document.body.appendChild(a)
+ a.click()
+ window.URL.revokeObjectURL(url)
+}
diff --git a/frontend/src/utils/query.ts b/frontend/src/utils/query.ts
new file mode 100644
index 00000000..9ec154c6
--- /dev/null
+++ b/frontend/src/utils/query.ts
@@ -0,0 +1,19 @@
+export type QueryBodyInput = {
+ select_columns: string
+ filter: string
+ group_by_columns: string
+ aggregation_conditions: string
+ limit: string
+}
+
+// Builds the API payload from form state, dropping empty fields and
+// splitting comma-separated lists into arrays.
+export function buildQueryPayload(queryBody: QueryBodyInput): Record {
+ const payload: Record = {}
+ if (queryBody.select_columns) payload.select_columns = queryBody.select_columns.split(',')
+ if (queryBody.filter) payload.filter = queryBody.filter
+ if (queryBody.group_by_columns) payload.group_by_columns = queryBody.group_by_columns.split(',')
+ if (queryBody.aggregation_conditions) payload.aggregation_conditions = queryBody.aggregation_conditions
+ if (queryBody.limit) payload.limit = queryBody.limit
+ return payload
+}
diff --git a/frontend/src/utils/sort.ts b/frontend/src/utils/sort.ts
new file mode 100644
index 00000000..d348bfeb
--- /dev/null
+++ b/frontend/src/utils/sort.ts
@@ -0,0 +1,16 @@
+// Returns a stable copy of `items` sorted by the string value at `key`.
+// Pass null/undefined for `key` to skip sorting and return `items` unchanged.
+// Comparison is case- and accent-insensitive.
+export function sortByString(
+ items: T[],
+ key: keyof T | null | undefined,
+ direction: 'asc' | 'desc'
+): T[] {
+ if (!key) return items
+ const sign = direction === 'asc' ? 1 : -1
+ return [...items].sort((a, b) =>
+ String(a[key] ?? '').localeCompare(String(b[key] ?? ''), undefined, {
+ sensitivity: 'base'
+ }) * sign
+ )
+}
diff --git a/frontend/src/utils/url.test.ts b/frontend/src/utils/url.test.ts
index 8caa39dc..26a51c17 100644
--- a/frontend/src/utils/url.test.ts
+++ b/frontend/src/utils/url.test.ts
@@ -19,23 +19,6 @@ describe('createUrl()', () => {
describe('isUrlInternal()', () => {
const sitename = 'http://myapp/'
- const { location } = window
-
- beforeAll(() => {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- delete (window as any).location
- })
-
- afterAll(() => {
- window.location = location
- })
-
- beforeEach(() => {
- window.location = {
- ...location,
- href: sitename
- }
- })
it('url is only path', () => {
expect(isUrlInternal('/someurl')).toBeTruthy()
@@ -43,9 +26,9 @@ describe('isUrlInternal()', () => {
})
it('url contains full site', () => {
- expect(isUrlInternal(sitename)).toBeTruthy()
- expect(isUrlInternal(sitename + 'product/')).toBeTruthy()
- expect(isUrlInternal(sitename + '?param=1')).toBeTruthy()
+ expect(isUrlInternal(sitename, sitename)).toBeTruthy()
+ expect(isUrlInternal(sitename + 'product/', sitename)).toBeTruthy()
+ expect(isUrlInternal(sitename + '?param=1', sitename)).toBeTruthy()
})
it('throws error if invalid url', () => {
@@ -59,7 +42,7 @@ describe('isUrlInternal()', () => {
})
it('url is external site', () => {
- expect(isUrlInternal('http://externalapp/')).toBeFalsy()
- expect(isUrlInternal('https://myapp/')).toBeFalsy()
+ expect(isUrlInternal('http://externalapp/', sitename)).toBeFalsy()
+ expect(isUrlInternal('https://myapp/', sitename)).toBeFalsy()
})
})
diff --git a/infrastructure/scripts/infra_make_helper.sh b/infrastructure/scripts/infra_make_helper.sh
index dec221d7..4372cd47 100755
--- a/infrastructure/scripts/infra_make_helper.sh
+++ b/infrastructure/scripts/infra_make_helper.sh
@@ -49,9 +49,10 @@ function run_tf() {
function run_init() {
local block="$1"
+ local extra_args="${2:-}"
_go_to_block "$block"
local config_path="${CONFIG_DIR}/backend.hcl"
- local cmd="init -backend-config ${config_path}"
+ local cmd="init -backend-config ${config_path} ${extra_args}"
echo "$TERRAFORM $cmd" |bash
}