From fc857d987bbb872ed3cc636fdc4826e3fe568b43 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Wed, 9 Oct 2024 13:25:44 -0300 Subject: [PATCH 01/23] fix: Unable to parse escaped tables (#30560) --- superset/config.py | 5 +++ superset/initialization/__init__.py | 5 +++ superset/sql_parse.py | 63 +++-------------------------- tests/unit_tests/sql/parse_tests.py | 13 ++++++ 4 files changed, 29 insertions(+), 57 deletions(-) diff --git a/superset/config.py b/superset/config.py index 0234c0deb230b..f0ba25a3eb088 100644 --- a/superset/config.py +++ b/superset/config.py @@ -68,6 +68,7 @@ if TYPE_CHECKING: from flask_appbuilder.security.sqla import models + from sqlglot import Dialect, Dialects from superset.connectors.sqla.models import SqlaTable from superset.models.core import Database @@ -249,6 +250,10 @@ def _try_json_readsha(filepath: str, length: int) -> str | None: SQLALCHEMY_ENCRYPTED_FIELD_TYPE_ADAPTER = ( # pylint: disable=invalid-name SQLAlchemyUtilsAdapter ) + +# Extends the default SQLGlot dialects with additional dialects +SQLGLOT_DIALECTS_EXTENSIONS: map[str, Dialects | type[Dialect]] = {} + # The limit of queries fetched for query search QUERY_SEARCH_LIMIT = 1000 diff --git a/superset/initialization/__init__.py b/superset/initialization/__init__.py index 10686b872ff41..1720c87af48e2 100644 --- a/superset/initialization/__init__.py +++ b/superset/initialization/__init__.py @@ -54,6 +54,7 @@ talisman, ) from superset.security import SupersetSecurityManager +from superset.sql.parse import SQLGLOT_DIALECTS from superset.superset_typing import FlaskResponse from superset.tags.core import register_sqla_event_listeners from superset.utils.core import is_test, pessimistic_connection_handling @@ -484,6 +485,7 @@ def init_app(self) -> None: self.configure_middlewares() self.configure_cache() self.set_db_default_isolation() + self.configure_sqlglot_dialects() with self.superset_app.app_context(): self.init_app_in_ctx() @@ -544,6 +546,9 @@ def configure_cache(self) -> None: def configure_feature_flags(self) -> None: feature_flag_manager.init_app(self.superset_app) + def configure_sqlglot_dialects(self) -> None: + SQLGLOT_DIALECTS.update(self.config["SQLGLOT_DIALECTS_EXTENSIONS"]) + @transaction() def configure_fab(self) -> None: if self.config["SILENCE_FAB"]: diff --git a/superset/sql_parse.py b/superset/sql_parse.py index 91b68126356a2..1581b0c6e79e6 100644 --- a/superset/sql_parse.py +++ b/superset/sql_parse.py @@ -28,7 +28,6 @@ from flask_babel import gettext as __ from jinja2 import nodes from sqlalchemy import and_ -from sqlglot.dialects.dialect import Dialects from sqlparse import keywords from sqlparse.lexer import Lexer from sqlparse.sql import ( @@ -61,7 +60,12 @@ SupersetParseError, SupersetSecurityException, ) -from superset.sql.parse import extract_tables_from_statement, SQLScript, Table +from superset.sql.parse import ( + extract_tables_from_statement, + SQLGLOT_DIALECTS, + SQLScript, + Table, +) from superset.utils.backports import StrEnum try: @@ -88,61 +92,6 @@ lex.set_SQL_REGEX(sqlparser_sql_regex) -# mapping between DB engine specs and sqlglot dialects -SQLGLOT_DIALECTS = { - "ascend": Dialects.HIVE, - "awsathena": Dialects.PRESTO, - "bigquery": Dialects.BIGQUERY, - "clickhouse": Dialects.CLICKHOUSE, - "clickhousedb": Dialects.CLICKHOUSE, - "cockroachdb": Dialects.POSTGRES, - "couchbase": Dialects.MYSQL, - # "crate": ??? - # "databend": ??? - "databricks": Dialects.DATABRICKS, - # "db2": ??? - # "dremio": ??? - "drill": Dialects.DRILL, - # "druid": ??? - "duckdb": Dialects.DUCKDB, - # "dynamodb": ??? - # "elasticsearch": ??? - # "exa": ??? - # "firebird": ??? - # "firebolt": ??? - "gsheets": Dialects.SQLITE, - "hana": Dialects.POSTGRES, - "hive": Dialects.HIVE, - # "ibmi": ??? - # "impala": ??? - # "kustokql": ??? - # "kylin": ??? - "mssql": Dialects.TSQL, - "mysql": Dialects.MYSQL, - "netezza": Dialects.POSTGRES, - # "ocient": ??? - # "odelasticsearch": ??? - "oracle": Dialects.ORACLE, - # "pinot": ??? - "postgresql": Dialects.POSTGRES, - "presto": Dialects.PRESTO, - "pydoris": Dialects.DORIS, - "redshift": Dialects.REDSHIFT, - # "risingwave": ??? - # "rockset": ??? - "shillelagh": Dialects.SQLITE, - "snowflake": Dialects.SNOWFLAKE, - # "solr": ??? - "spark": Dialects.SPARK, - "sqlite": Dialects.SQLITE, - "starrocks": Dialects.STARROCKS, - "superset": Dialects.SQLITE, - "teradatasql": Dialects.TERADATA, - "trino": Dialects.TRINO, - "vertica": Dialects.POSTGRES, -} - - class CtasMethod(StrEnum): TABLE = "TABLE" VIEW = "VIEW" diff --git a/tests/unit_tests/sql/parse_tests.py b/tests/unit_tests/sql/parse_tests.py index 6c1e5791277b3..ae5ebf89a8b96 100644 --- a/tests/unit_tests/sql/parse_tests.py +++ b/tests/unit_tests/sql/parse_tests.py @@ -18,6 +18,7 @@ import pytest +from sqlglot import Dialects from superset.exceptions import SupersetParseError from superset.sql.parse import ( @@ -932,3 +933,15 @@ def test_get_settings() -> None: SELECT * FROM some_table; """ assert SQLScript(sql, "postgresql").get_settings() == {"search_path": "bar"} + + +@pytest.mark.parametrize( + "app", + [{"SQLGLOT_DIALECTS_EXTENSIONS": {"custom": Dialects.MYSQL}}], + indirect=True, +) +def test_custom_dialect(app: None) -> None: + """ + Test that custom dialects are loaded correctly. + """ + assert SQLGLOT_DIALECTS.get("custom") == Dialects.MYSQL From 7b47e43fd098d336b5e383d4656477bad0b45430 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:22:17 -0300 Subject: [PATCH 02/23] fix: Horizon Chart are not working any more (#30563) --- .../plugins/legacy-plugin-chart-horizon/src/controlPanel.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/superset-frontend/plugins/legacy-plugin-chart-horizon/src/controlPanel.ts b/superset-frontend/plugins/legacy-plugin-chart-horizon/src/controlPanel.ts index c96b2f0ed7f32..51a43a450e119 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-horizon/src/controlPanel.ts +++ b/superset-frontend/plugins/legacy-plugin-chart-horizon/src/controlPanel.ts @@ -24,6 +24,12 @@ import { const config: ControlPanelConfig = { controlPanelSections: [ + { + label: t('Time'), + expanded: true, + description: t('Time related form attributes'), + controlSetRows: [['granularity_sqla'], ['time_range']], + }, { label: t('Query'), expanded: true, From 7a8e8f890fe521f2d8fadde5a3f9850563e67084 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:29:11 -0300 Subject: [PATCH 03/23] fix: Incorrect type in config.py (#30564) --- superset/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset/config.py b/superset/config.py index f0ba25a3eb088..7ae46bba76f36 100644 --- a/superset/config.py +++ b/superset/config.py @@ -252,7 +252,7 @@ def _try_json_readsha(filepath: str, length: int) -> str | None: ) # Extends the default SQLGlot dialects with additional dialects -SQLGLOT_DIALECTS_EXTENSIONS: map[str, Dialects | type[Dialect]] = {} +SQLGLOT_DIALECTS_EXTENSIONS: dict[str, Dialects | type[Dialect]] = {} # The limit of queries fetched for query search QUERY_SEARCH_LIMIT = 1000 From 211564a6da5fa76210396e858d4d1acbe7cba950 Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 9 Oct 2024 20:36:46 +0200 Subject: [PATCH 04/23] fix(dashboard-export): Fixes datasetId is not replaced with datasetUuid in Dashboard export in 4.1.x (#30425) --- superset/commands/dashboard/export.py | 34 +++++++++----- .../dashboards/commands_tests.py | 45 +++++++++++++++++++ 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/superset/commands/dashboard/export.py b/superset/commands/dashboard/export.py index fe3a6b8eab871..93cc490ad73de 100644 --- a/superset/commands/dashboard/export.py +++ b/superset/commands/dashboard/export.py @@ -130,6 +130,18 @@ def _file_content(model: Dashboard) -> str: logger.info("Unable to decode `%s` field: %s", key, value) payload[new_name] = {} + # Extract all native filter datasets and replace native + # filter dataset references with uuid + for native_filter in payload.get("metadata", {}).get( + "native_filter_configuration", [] + ): + for target in native_filter.get("targets", []): + dataset_id = target.pop("datasetId", None) + if dataset_id is not None: + dataset = DatasetDAO.find_by_id(dataset_id) + if dataset: + target["datasetUuid"] = str(dataset.uuid) + # the mapping between dashboard -> charts is inferred from the position # attribute, so if it's not present we need to add a default config if not payload.get("position"): @@ -180,16 +192,14 @@ def _export( logger.info("Unable to decode `%s` field: %s", key, value) payload[new_name] = {} - # Extract all native filter datasets and replace native - # filter dataset references with uuid - for native_filter in payload.get("metadata", {}).get( - "native_filter_configuration", [] - ): - for target in native_filter.get("targets", []): - dataset_id = target.pop("datasetId", None) - if dataset_id is not None: - dataset = DatasetDAO.find_by_id(dataset_id) - if dataset: - target["datasetUuid"] = str(dataset.uuid) - if export_related: + if export_related: + # Extract all native filter datasets and export referenced datasets + for native_filter in payload.get("metadata", {}).get( + "native_filter_configuration", [] + ): + for target in native_filter.get("targets", []): + dataset_id = target.pop("datasetId", None) + if dataset_id is not None: + dataset = DatasetDAO.find_by_id(dataset_id) + if dataset: yield from ExportDatasetsCommand([dataset_id]).run() diff --git a/tests/integration_tests/dashboards/commands_tests.py b/tests/integration_tests/dashboards/commands_tests.py index 451d924cd6c6e..38606a130403f 100644 --- a/tests/integration_tests/dashboards/commands_tests.py +++ b/tests/integration_tests/dashboards/commands_tests.py @@ -238,6 +238,51 @@ def test_export_dashboard_command(self, mock_g1, mock_g2): "version": "1.0.0", } + # @pytest.mark.usefixtures("load_covid_dashboard") + @pytest.mark.skip(reason="missing covid fixture") + @patch("superset.security.manager.g") + @patch("superset.views.base.g") + def test_export_dashboard_command_dataset_references(self, mock_g1, mock_g2): + mock_g1.user = security_manager.find_user("admin") + mock_g2.user = security_manager.find_user("admin") + + example_dashboard = ( + db.session.query(Dashboard) + .filter_by(uuid="f4065089-110a-41fa-8dd7-9ce98a65e250") + .one() + ) + command = ExportDashboardsCommand([example_dashboard.id]) + contents = dict(command.run()) + + expected_paths = { + "metadata.yaml", + f"dashboards/COVID_Vaccine_Dashboard_{example_dashboard.id}.yaml", + "datasets/examples/covid_vaccines.yaml", # referenced dataset needs to be exported + "databases/examples.yaml", + } + for chart in example_dashboard.slices: + chart_slug = secure_filename(chart.slice_name) + expected_paths.add(f"charts/{chart_slug}_{chart.id}.yaml") + assert expected_paths == set(contents.keys()) + + metadata = yaml.safe_load( + contents[f"dashboards/World_Banks_Data_{example_dashboard.id}.yaml"]() + ) + + # find the dataset references in native filter and check if they are correct + assert "native_filter_configuration" in metadata["metadata"] + + for filter_config in metadata["metadata"][ + "native_filter_configuration" + ].values(): + assert "targets" in filter_config + targets = filter_config["targets"] + + for column in targets: + # we need to find the correct datasetUuid (not datasetId) + assert "datasetUuid" in column + assert column["datasetUuid"] == "974b7a1c-22ea-49cb-9214-97b7dbd511e0" + @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") @patch("superset.security.manager.g") @patch("superset.views.base.g") From 318eff732764f89e49c6eb699238c8950f533726 Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Wed, 9 Oct 2024 23:26:32 +0300 Subject: [PATCH 05/23] fix(Jinja): Extra cache keys to consider vars with set (#30549) --- superset/jinja_context.py | 15 +- tests/integration_tests/sqla_models_tests.py | 194 ++++++++++++------- 2 files changed, 134 insertions(+), 75 deletions(-) diff --git a/superset/jinja_context.py b/superset/jinja_context.py index d7ae892301689..e4a83422315d8 100644 --- a/superset/jinja_context.py +++ b/superset/jinja_context.py @@ -104,13 +104,14 @@ class ExtraCache: # Regular expression for detecting the presence of templated methods which could # be added to the cache key. regex = re.compile( - r"\{\{.*(" - r"current_user_id\(.*\)|" - r"current_username\(.*\)|" - r"current_user_email\(.*\)|" - r"cache_key_wrapper\(.*\)|" - r"url_param\(.*\)" - r").*\}\}" + r"(\{\{|\{%)[^{}]*?(" + r"current_user_id\([^()]*\)|" + r"current_username\([^()]*\)|" + r"current_user_email\([^()]*\)|" + r"cache_key_wrapper\([^()]*\)|" + r"url_param\([^()]*\)" + r")" + r"[^{}]*?(\}\}|\%\})" ) def __init__( # pylint: disable=too-many-arguments diff --git a/tests/integration_tests/sqla_models_tests.py b/tests/integration_tests/sqla_models_tests.py index fb03f37e62c7b..922cbf67fd65e 100644 --- a/tests/integration_tests/sqla_models_tests.py +++ b/tests/integration_tests/sqla_models_tests.py @@ -133,74 +133,6 @@ def test_db_column_types(self): col = TableColumn(column_name="foo", type=str_type, table=tbl, is_dttm=True) assert col.is_temporal - @patch("superset.jinja_context.get_user_id", return_value=1) - @patch("superset.jinja_context.get_username", return_value="abc") - @patch("superset.jinja_context.get_user_email", return_value="abc@test.com") - def test_extra_cache_keys(self, mock_user_email, mock_username, mock_user_id): - base_query_obj = { - "granularity": None, - "from_dttm": None, - "to_dttm": None, - "groupby": ["id", "username", "email"], - "metrics": [], - "is_timeseries": False, - "filter": [], - } - - # Table with Jinja callable. - table1 = SqlaTable( - table_name="test_has_extra_cache_keys_table", - sql=""" - SELECT - '{{ current_user_id() }}' as id, - '{{ current_username() }}' as username, - '{{ current_user_email() }}' as email - """, - database=get_example_database(), - ) - - query_obj = dict(**base_query_obj, extras={}) - extra_cache_keys = table1.get_extra_cache_keys(query_obj) - assert table1.has_extra_cache_key_calls(query_obj) - assert set(extra_cache_keys) == {1, "abc", "abc@test.com"} - - # Table with Jinja callable disabled. - table2 = SqlaTable( - table_name="test_has_extra_cache_keys_disabled_table", - sql=""" - SELECT - '{{ current_user_id(False) }}' as id, - '{{ current_username(False) }}' as username, - '{{ current_user_email(False) }}' as email, - """, - database=get_example_database(), - ) - query_obj = dict(**base_query_obj, extras={}) - extra_cache_keys = table2.get_extra_cache_keys(query_obj) - assert table2.has_extra_cache_key_calls(query_obj) - self.assertListEqual(extra_cache_keys, []) # noqa: PT009 - - # Table with no Jinja callable. - query = "SELECT 'abc' as user" - table3 = SqlaTable( - table_name="test_has_no_extra_cache_keys_table", - sql=query, - database=get_example_database(), - ) - - query_obj = dict(**base_query_obj, extras={"where": "(user != 'abc')"}) - extra_cache_keys = table3.get_extra_cache_keys(query_obj) - assert not table3.has_extra_cache_key_calls(query_obj) - self.assertListEqual(extra_cache_keys, []) # noqa: PT009 - - # With Jinja callable in SQL expression. - query_obj = dict( - **base_query_obj, extras={"where": "(user != '{{ current_username() }}')"} - ) - extra_cache_keys = table3.get_extra_cache_keys(query_obj) - assert table3.has_extra_cache_key_calls(query_obj) - assert extra_cache_keys == ["abc"] - @patch("superset.jinja_context.get_username", return_value="abc") def test_jinja_metrics_and_calc_columns(self, mock_username): base_query_obj = { @@ -859,6 +791,132 @@ def test_none_operand_in_filter(login_as_admin, physical_dataset): ) +@pytest.mark.usefixtures("app_context") +@pytest.mark.parametrize( + "table_name,sql,expected_cache_keys,has_extra_cache_keys", + [ + ( + "test_has_extra_cache_keys_table", + """ + SELECT + '{{ current_user_id() }}' as id, + '{{ current_username() }}' as username, + '{{ current_user_email() }}' as email + """, + {1, "abc", "abc@test.com"}, + True, + ), + ( + "test_has_extra_cache_keys_table_with_set", + """ + {% set user_email = current_user_email() %} + SELECT + '{{ current_user_id() }}' as id, + '{{ current_username() }}' as username, + '{{ user_email }}' as email + """, + {1, "abc", "abc@test.com"}, + True, + ), + ( + "test_has_extra_cache_keys_table_with_se_multiple", + """ + {% set user_conditional_id = current_user_email() and current_user_id() %} + SELECT + '{{ user_conditional_id }}' as conditional + """, + {1, "abc@test.com"}, + True, + ), + ( + "test_has_extra_cache_keys_disabled_table", + """ + SELECT + '{{ current_user_id(False) }}' as id, + '{{ current_username(False) }}' as username, + '{{ current_user_email(False) }}' as email + """, + [], + True, + ), + ("test_has_no_extra_cache_keys_table", "SELECT 'abc' as user", [], False), + ], +) +@patch("superset.jinja_context.get_user_id", return_value=1) +@patch("superset.jinja_context.get_username", return_value="abc") +@patch("superset.jinja_context.get_user_email", return_value="abc@test.com") +def test_extra_cache_keys( + mock_user_email, + mock_username, + mock_user_id, + table_name, + sql, + expected_cache_keys, + has_extra_cache_keys, +): + table = SqlaTable( + table_name=table_name, + sql=sql, + database=get_example_database(), + ) + base_query_obj = { + "granularity": None, + "from_dttm": None, + "to_dttm": None, + "groupby": ["id", "username", "email"], + "metrics": [], + "is_timeseries": False, + "filter": [], + } + + query_obj = dict(**base_query_obj, extras={}) + + extra_cache_keys = table.get_extra_cache_keys(query_obj) + assert table.has_extra_cache_key_calls(query_obj) == has_extra_cache_keys + assert set(extra_cache_keys) == set(expected_cache_keys) + + +@pytest.mark.usefixtures("app_context") +@pytest.mark.parametrize( + "sql_expression,expected_cache_keys,has_extra_cache_keys", + [ + ("(user != '{{ current_username() }}')", ["abc"], True), + ("(user != 'abc')", [], False), + ], +) +@patch("superset.jinja_context.get_user_id", return_value=1) +@patch("superset.jinja_context.get_username", return_value="abc") +@patch("superset.jinja_context.get_user_email", return_value="abc@test.com") +def test_extra_cache_keys_in_sql_expression( + mock_user_email, + mock_username, + mock_user_id, + sql_expression, + expected_cache_keys, + has_extra_cache_keys, +): + table = SqlaTable( + table_name="test_has_no_extra_cache_keys_table", + sql="SELECT 'abc' as user", + database=get_example_database(), + ) + base_query_obj = { + "granularity": None, + "from_dttm": None, + "to_dttm": None, + "groupby": ["id", "username", "email"], + "metrics": [], + "is_timeseries": False, + "filter": [], + } + + query_obj = dict(**base_query_obj, extras={"where": sql_expression}) + + extra_cache_keys = table.get_extra_cache_keys(query_obj) + assert table.has_extra_cache_key_calls(query_obj) == has_extra_cache_keys + assert extra_cache_keys == expected_cache_keys + + @pytest.mark.usefixtures("app_context") @pytest.mark.parametrize( "row,dimension,result", From 62b94d5abf3caa5fdd80d1f37eb22667a4fc03f9 Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:59:26 +0300 Subject: [PATCH 06/23] fix(dev-server): Revert "chore(fe): bump webpack-related packages to v5" (#30569) --- superset-embedded-sdk/package-lock.json | 15 +- superset-embedded-sdk/package.json | 2 +- superset-frontend/package-lock.json | 1007 ++++++++++------------- superset-frontend/package.json | 6 +- superset-frontend/webpack.config.js | 16 +- 5 files changed, 448 insertions(+), 598 deletions(-) diff --git a/superset-embedded-sdk/package-lock.json b/superset-embedded-sdk/package-lock.json index d762b917cdaee..48f7c770ebc99 100644 --- a/superset-embedded-sdk/package-lock.json +++ b/superset-embedded-sdk/package-lock.json @@ -23,7 +23,7 @@ "babel-loader": "^9.1.3", "jest": "^29.7.0", "typescript": "^5.6.2", - "webpack": "^5.95.0", + "webpack": "^5.94.0", "webpack-cli": "^5.1.4" } }, @@ -7972,11 +7972,10 @@ } }, "node_modules/webpack": { - "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", @@ -13937,9 +13936,9 @@ } }, "webpack": { - "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "requires": { "@types/estree": "^1.0.5", diff --git a/superset-embedded-sdk/package.json b/superset-embedded-sdk/package.json index fc7c8988432ac..44cdd4f0e9ce7 100644 --- a/superset-embedded-sdk/package.json +++ b/superset-embedded-sdk/package.json @@ -47,7 +47,7 @@ "babel-loader": "^9.1.3", "jest": "^29.7.0", "typescript": "^5.6.2", - "webpack": "^5.95.0", + "webpack": "^5.94.0", "webpack-cli": "^5.1.4" }, "repository": { diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 8d63babcb258f..1c452cb65330e 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -284,10 +284,10 @@ "ts-loader": "^9.5.1", "typescript": "^4.8.4", "vm-browserify": "^1.1.2", - "webpack": "^5.95.0", + "webpack": "^5.94.0", "webpack-bundle-analyzer": "^4.10.1", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.1.0", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.15.1", "webpack-manifest-plugin": "^5.0.0", "webpack-sources": "^3.2.3", "webpack-visualizer-plugin2": "^1.1.0", @@ -6291,9 +6291,7 @@ "license": "MIT" }, "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "version": "2.0.4", "dev": true, "license": "MIT" }, @@ -13225,9 +13223,7 @@ } }, "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "version": "3.5.10", "dev": true, "license": "MIT", "dependencies": { @@ -13264,9 +13260,7 @@ } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "version": "1.3.5", "dev": true, "license": "MIT", "dependencies": { @@ -13522,12 +13516,6 @@ "version": "4.0.4", "license": "MIT" }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "license": "MIT" - }, "node_modules/@types/http-proxy": { "version": "1.17.9", "dev": true, @@ -13691,6 +13679,10 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mime": { + "version": "3.0.1", + "license": "MIT" + }, "node_modules/@types/minimatch": { "version": "3.0.5", "license": "MIT" @@ -13718,16 +13710,6 @@ "undici-types": "~6.19.2" } }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/node/node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -13968,9 +13950,7 @@ "license": "MIT" }, "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "version": "1.9.1", "dev": true, "license": "MIT", "dependencies": { @@ -13978,14 +13958,11 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "version": "1.15.0", "license": "MIT", "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" + "@types/mime": "*", + "@types/node": "*" } }, "node_modules/@types/sinon": { @@ -14008,9 +13985,7 @@ "license": "MIT" }, "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "version": "0.3.33", "dev": true, "license": "MIT", "dependencies": { @@ -15640,45 +15615,31 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "version": "1.2.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "version": "1.5.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=14.15.0" + "dependencies": { + "envinfo": "^7.7.3" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack-cli": "4.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "version": "1.7.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack-cli": "4.x.x" }, "peerDependenciesMeta": { "webpack-dev-server": { @@ -18336,12 +18297,12 @@ } }, "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "version": "1.0.14", "dev": true, "license": "MIT", "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } @@ -21806,6 +21767,134 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/default-gateway": { + "version": "6.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/default-gateway/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/default-gateway/node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/default-gateway/node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway/node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/default-gateway/node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway/node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/default-gateway/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/default-gateway/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/default-gateway/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/default-gateway/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/default-require-extensions": { "version": "3.0.0", "dev": true, @@ -22318,10 +22407,13 @@ "redux": "^4.0.4" } }, + "node_modules/dns-equal": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "version": "5.4.0", "dev": true, "license": "MIT", "dependencies": { @@ -28268,20 +28360,8 @@ } }, "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "version": "2.3.2", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], "license": "MIT" }, "node_modules/html-escaper": { @@ -28633,16 +28713,6 @@ "node": ">=8.12.0" } }, - "node_modules/hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.18" - } - }, "node_modules/hyphenate-style-name": { "version": "1.0.4", "license": "BSD-3-Clause" @@ -29026,13 +29096,11 @@ "license": "ISC" }, "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "version": "2.2.0", "dev": true, "license": "MIT", "engines": { - "node": ">=10.13.0" + "node": ">= 0.10" } }, "node_modules/interweave": { @@ -29079,9 +29147,7 @@ "license": "BSD-3-Clause" }, "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "version": "2.0.1", "dev": true, "license": "MIT", "engines": { @@ -29497,19 +29563,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-network-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", - "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-number": { "version": "3.0.0", "dev": true, @@ -33083,14 +33136,12 @@ } }, "node_modules/launch-editor": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", - "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "version": "2.6.0", "dev": true, "license": "MIT", "dependencies": { "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" + "shell-quote": "^1.7.3" } }, "node_modules/lazy-ass": { @@ -40043,8 +40094,6 @@ }, "node_modules/multicast-dns": { "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, "license": "MIT", "dependencies": { @@ -40384,8 +40433,6 @@ }, "node_modules/node-forge": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "dev": true, "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { @@ -46315,19 +46362,6 @@ "version": "2.6.3", "license": "0BSD" }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/recompose": { "version": "0.23.5", "license": "MIT", @@ -48354,13 +48388,10 @@ "license": "MIT" }, "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "version": "2.1.1", "dev": true, "license": "MIT", "dependencies": { - "@types/node-forge": "^1.3.0", "node-forge": "^1" }, "engines": { @@ -50735,8 +50766,6 @@ }, "node_modules/thunky": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true, "license": "MIT" }, @@ -52405,11 +52434,10 @@ "license": "BSD-2-Clause" }, "node_modules/webpack": { - "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "devOptional": true, - "license": "MIT", "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", @@ -52527,43 +52555,43 @@ } }, "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "version": "4.10.0", "dev": true, "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", "colorette": "^2.0.14", - "commander": "^10.0.1", + "commander": "^7.0.0", "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", "webpack-merge": "^5.7.3" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=14.15.0" + "node": ">=10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "5.x.x" + "webpack": "4.x.x || 5.x.x" }, "peerDependenciesMeta": { "@webpack-cli/generators": { "optional": true }, + "@webpack-cli/migrate": { + "optional": true + }, "webpack-bundle-analyzer": { "optional": true }, @@ -52578,13 +52606,11 @@ "license": "MIT" }, "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "version": "7.2.0", "dev": true, "license": "MIT", "engines": { - "node": ">=14" + "node": ">= 10" } }, "node_modules/webpack-cli/node_modules/cross-spawn": { @@ -52608,6 +52634,17 @@ "node": ">=8" } }, + "node_modules/webpack-cli/node_modules/rechoir": { + "version": "0.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/webpack-cli/node_modules/shebang-command": { "version": "2.0.0", "dev": true, @@ -52723,53 +52760,53 @@ } }, "node_modules/webpack-dev-server": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.1.0.tgz", - "integrity": "sha512-aQpaN81X6tXie1FoOB7xlMfCsN19pSvRAeYUHOdFWOlhpQ/LlbfTqYwwmEDFV0h8GGuqmCmKmT+pxcUV/Nt2gQ==", + "version": "4.15.1", "dev": true, "license": "MIT", "dependencies": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^4.17.21", - "@types/serve-index": "^1.9.4", - "@types/serve-static": "^1.15.5", - "@types/sockjs": "^0.3.36", - "@types/ws": "^8.5.10", + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.2.1", - "chokidar": "^3.6.0", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", "colorette": "^2.0.10", "compression": "^1.7.4", "connect-history-api-fallback": "^2.0.0", - "express": "^4.19.2", + "default-gateway": "^6.0.3", + "express": "^4.17.3", "graceful-fs": "^4.2.6", - "html-entities": "^2.4.0", + "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "schema-utils": "^4.2.0", - "selfsigned": "^2.4.1", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^7.4.2", - "ws": "^8.18.0" + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { - "node": ">= 18.12.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" + "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { "webpack": { @@ -52780,91 +52817,15 @@ } } }, - "node_modules/webpack-dev-server/node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/webpack-dev-server/node_modules/@jsonjoy.com/json-pack": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", - "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/base64": "^1.1.1", - "@jsonjoy.com/util": "^1.1.2", - "hyperdyperid": "^1.2.0", - "thingies": "^1.20.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/webpack-dev-server/node_modules/@jsonjoy.com/util": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz", - "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/webpack-dev-server/node_modules/@types/retry": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", - "dev": true, - "license": "MIT" - }, - "node_modules/webpack-dev-server/node_modules/@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.11.0", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", + "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, "funding": { "type": "github", @@ -52873,8 +52834,6 @@ }, "node_modules/webpack-dev-server/node_modules/ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "license": "MIT", "dependencies": { @@ -52885,68 +52844,64 @@ } }, "node_modules/webpack-dev-server/node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "version": "2.0.19", "dev": true, "license": "MIT" }, + "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, - "node_modules/webpack-dev-server/node_modules/memfs": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz", - "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==", + "node_modules/webpack-dev-server/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/json-pack": "^1.0.3", - "@jsonjoy.com/util": "^1.3.0", - "tree-dump": "^1.0.1", - "tslib": "^2.0.0" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">= 4.0.0" + "node": ">=12" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/webpack-dev-server/node_modules/p-retry": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", - "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "node_modules/webpack-dev-server/node_modules/rimraf": { + "version": "3.0.2", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" + "glob": "^7.1.3" }, - "engines": { - "node": ">=16.17" + "bin": { + "rimraf": "bin.js" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "version": "4.0.0", "dev": true, "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", + "ajv": "^8.8.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "ajv-keywords": "^5.0.0" }, "engines": { "node": ">= 12.13.0" @@ -52956,71 +52911,26 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/webpack-dev-server/node_modules/thingies": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", - "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", - "dev": true, - "license": "Unlicense", - "engines": { - "node": ">=10.18" - }, - "peerDependencies": { - "tslib": "^2" - } - }, - "node_modules/webpack-dev-server/node_modules/tree-dump": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", - "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/webpack-dev-server/node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "dev": true, - "license": "0BSD" - }, "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", - "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "version": "5.3.4", "dev": true, "license": "MIT", "dependencies": { "colorette": "^2.0.10", - "memfs": "^4.6.0", + "memfs": "^3.4.3", "mime-types": "^2.1.31", - "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 18.12.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } + "webpack": "^4.0.0 || ^5.0.0" } }, "node_modules/webpack-dev-server/node_modules/ws": { @@ -61990,9 +61900,7 @@ "version": "1.1.1" }, "@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "version": "2.0.4", "dev": true }, "@lerna/create": { @@ -68937,9 +68845,7 @@ } }, "@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "version": "3.5.10", "dev": true, "requires": { "@types/node": "*" @@ -68971,9 +68877,7 @@ } }, "@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "version": "1.3.5", "dev": true, "requires": { "@types/express-serve-static-core": "*", @@ -69189,11 +69093,6 @@ "@types/http-cache-semantics": { "version": "4.0.4" }, - "@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, "@types/http-proxy": { "version": "1.17.9", "dev": true, @@ -69328,6 +69227,9 @@ "version": "2.0.11", "dev": true }, + "@types/mime": { + "version": "3.0.1" + }, "@types/minimatch": { "version": "3.0.5" }, @@ -69359,15 +69261,6 @@ } } }, - "@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/normalize-package-data": { "version": "2.4.4" }, @@ -69576,22 +69469,17 @@ } }, "@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "version": "1.9.1", "dev": true, "requires": { "@types/express": "*" } }, "@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "version": "1.15.0", "requires": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" + "@types/mime": "*", + "@types/node": "*" } }, "@types/sinon": { @@ -69612,9 +69500,7 @@ "dev": true }, "@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "version": "0.3.33", "dev": true, "requires": { "@types/node": "*" @@ -70760,23 +70646,19 @@ } }, "@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "version": "1.2.0", "dev": true, "requires": {} }, "@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "version": "1.5.0", "dev": true, - "requires": {} + "requires": { + "envinfo": "^7.7.3" + } }, "@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "version": "1.7.0", "dev": true, "requires": {} }, @@ -72555,11 +72437,11 @@ } }, "bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "version": "1.0.14", "dev": true, "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } @@ -74885,6 +74767,80 @@ "untildify": "^4.0.0" } }, + "default-gateway": { + "version": "6.0.3", + "dev": true, + "requires": { + "execa": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "5.1.1", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "dev": true + }, + "which": { + "version": "2.0.2", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "default-require-extensions": { "version": "3.0.0", "dev": true, @@ -75199,10 +75155,12 @@ "redux": "^4.0.4" } }, + "dns-equal": { + "version": "1.0.0", + "dev": true + }, "dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "version": "5.4.0", "dev": true, "requires": { "@leichtgewicht/ip-codec": "^2.0.1" @@ -79058,9 +79016,7 @@ } }, "html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "version": "2.3.2", "dev": true }, "html-escaper": { @@ -79274,12 +79230,6 @@ "dev": true, "peer": true }, - "hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", - "dev": true - }, "hyphenate-style-name": { "version": "1.0.4" }, @@ -79517,9 +79467,7 @@ "version": "1.0.1" }, "interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "version": "2.2.0", "dev": true }, "interweave": { @@ -79553,9 +79501,7 @@ } }, "ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "version": "2.0.1", "dev": true }, "is-absolute-url": { @@ -79784,12 +79730,6 @@ "version": "2.0.2", "dev": true }, - "is-network-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", - "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", - "dev": true - }, "is-number": { "version": "3.0.0", "dev": true, @@ -82152,13 +82092,11 @@ } }, "launch-editor": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", - "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "version": "2.6.0", "dev": true, "requires": { "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" + "shell-quote": "^1.7.3" } }, "lazy-ass": { @@ -86038,8 +85976,6 @@ }, "multicast-dns": { "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, "requires": { "dns-packet": "^5.2.2", @@ -86274,8 +86210,6 @@ }, "node-forge": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "dev": true }, "node-gyp": { @@ -90032,15 +89966,6 @@ } } }, - "rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "requires": { - "resolve": "^1.20.0" - } - }, "recompose": { "version": "0.23.5", "requires": { @@ -91279,12 +91204,9 @@ "dev": true }, "selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "version": "2.1.1", "dev": true, "requires": { - "@types/node-forge": "^1.3.0", "node-forge": "^1" } }, @@ -92880,8 +92802,6 @@ }, "thunky": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, "tilebelt": { @@ -93945,9 +93865,9 @@ "dev": true }, "webpack": { - "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "devOptional": true, "requires": { "@types/estree": "^1.0.5", @@ -94034,23 +93954,20 @@ } }, "webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "version": "4.10.0", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", + "@webpack-cli/configtest": "^1.2.0", + "@webpack-cli/info": "^1.5.0", + "@webpack-cli/serve": "^1.7.0", "colorette": "^2.0.14", - "commander": "^10.0.1", + "commander": "^7.0.0", "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", "webpack-merge": "^5.7.3" }, "dependencies": { @@ -94059,9 +93976,7 @@ "dev": true }, "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "version": "7.2.0", "dev": true }, "cross-spawn": { @@ -94077,6 +93992,13 @@ "version": "3.1.1", "dev": true }, + "rechoir": { + "version": "0.7.1", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, "shebang-command": { "version": "2.0.0", "dev": true, @@ -94146,180 +94068,107 @@ } }, "webpack-dev-server": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.1.0.tgz", - "integrity": "sha512-aQpaN81X6tXie1FoOB7xlMfCsN19pSvRAeYUHOdFWOlhpQ/LlbfTqYwwmEDFV0h8GGuqmCmKmT+pxcUV/Nt2gQ==", + "version": "4.15.1", "dev": true, "requires": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^4.17.21", - "@types/serve-index": "^1.9.4", - "@types/serve-static": "^1.15.5", - "@types/sockjs": "^0.3.36", - "@types/ws": "^8.5.10", + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.2.1", - "chokidar": "^3.6.0", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", "colorette": "^2.0.10", "compression": "^1.7.4", "connect-history-api-fallback": "^2.0.0", - "express": "^4.19.2", + "default-gateway": "^6.0.3", + "express": "^4.17.3", "graceful-fs": "^4.2.6", - "html-entities": "^2.4.0", + "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "schema-utils": "^4.2.0", - "selfsigned": "^2.4.1", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^7.4.2", - "ws": "^8.18.0" + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" }, "dependencies": { - "@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "dev": true, - "requires": {} - }, - "@jsonjoy.com/json-pack": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", - "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", - "dev": true, - "requires": { - "@jsonjoy.com/base64": "^1.1.1", - "@jsonjoy.com/util": "^1.1.2", - "hyperdyperid": "^1.2.0", - "thingies": "^1.20.0" - } - }, - "@jsonjoy.com/util": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz", - "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==", - "dev": true, - "requires": {} - }, - "@types/retry": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", - "dev": true - }, - "@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.11.0", "dev": true, "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", + "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, "ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.3" } }, "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "version": "2.0.19", + "dev": true + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true }, "json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "memfs": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz", - "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==", + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "requires": { - "@jsonjoy.com/json-pack": "^1.0.3", - "@jsonjoy.com/util": "^1.3.0", - "tree-dump": "^1.0.1", - "tslib": "^2.0.0" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" } }, - "p-retry": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", - "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "rimraf": { + "version": "3.0.2", "dev": true, "requires": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" + "glob": "^7.1.3" } }, "schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "version": "4.0.0", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", + "ajv": "^8.8.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "ajv-keywords": "^5.0.0" } }, - "thingies": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", - "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", - "dev": true, - "requires": {} - }, - "tree-dump": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", - "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", - "dev": true, - "requires": {} - }, - "tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "dev": true - }, "webpack-dev-middleware": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", - "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "version": "5.3.4", "dev": true, "requires": { "colorette": "^2.0.10", - "memfs": "^4.6.0", + "memfs": "^3.4.3", "mime-types": "^2.1.31", - "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" } diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 02eb74d2241f5..3dee70e069fda 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -350,10 +350,10 @@ "ts-loader": "^9.5.1", "typescript": "^4.8.4", "vm-browserify": "^1.1.2", - "webpack": "^5.95.0", + "webpack": "^5.94.0", "webpack-bundle-analyzer": "^4.10.1", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.1.0", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.15.1", "webpack-manifest-plugin": "^5.0.0", "webpack-sources": "^3.2.3", "webpack-visualizer-plugin2": "^1.1.0", diff --git a/superset-frontend/webpack.config.js b/superset-frontend/webpack.config.js index d4a74cc8771c6..10bf4d49eec1d 100644 --- a/superset-frontend/webpack.config.js +++ b/superset-frontend/webpack.config.js @@ -27,7 +27,10 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const MomentLocalesPlugin = require('moment-locales-webpack-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); -const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); +const { + WebpackManifestPlugin, + getCompilerHooks, +} = require('webpack-manifest-plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const parsedArgs = require('yargs').argv; const Visualizer = require('webpack-visualizer-plugin2'); @@ -542,15 +545,14 @@ let proxyConfig = getProxyConfig(); if (isDevMode) { config.devtool = 'eval-cheap-module-source-map'; - config.plugins.push({ - // Load proxy config when manifest updates - apply: compiler => { - compiler.hooks.afterEmit.tap('ManifestPlugin', manifest => { + config.devServer = { + onBeforeSetupMiddleware(devServer) { + // load proxy config when manifest updates + const { afterEmit } = getCompilerHooks(devServer.compiler); + afterEmit.tap('ManifestPlugin', manifest => { proxyConfig = getProxyConfig(manifest); }); }, - }); - config.devServer = { historyApiFallback: true, hot: true, port: devserverPort, From ef0ede7c13c7352e8b8ca4c5ba1cf73f622a36c4 Mon Sep 17 00:00:00 2001 From: Joe Li Date: Thu, 10 Oct 2024 10:19:26 -0700 Subject: [PATCH 07/23] fix: update html rendering to true from false (#30565) --- superset-frontend/src/SqlLab/components/ResultSet/index.tsx | 2 +- superset-frontend/src/SqlLab/components/SqlEditor/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/SqlLab/components/ResultSet/index.tsx b/superset-frontend/src/SqlLab/components/ResultSet/index.tsx index 3e9c9db5c6d48..7d0df189a2f21 100644 --- a/superset-frontend/src/SqlLab/components/ResultSet/index.tsx +++ b/superset-frontend/src/SqlLab/components/ResultSet/index.tsx @@ -646,7 +646,7 @@ const ResultSet = ({ : []; const allowHTML = getItem( LocalStorageKeys.SqllabIsRenderHtmlEnabled, - false, + true, ); return ( diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx index e5b24b72ad473..731053ac0b0b0 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx @@ -308,7 +308,7 @@ const SqlEditor: FC = ({ getItem(LocalStorageKeys.SqllabIsAutocompleteEnabled, true), ); const [renderHTMLEnabled, setRenderHTMLEnabled] = useState( - getItem(LocalStorageKeys.SqllabIsRenderHtmlEnabled, false), + getItem(LocalStorageKeys.SqllabIsRenderHtmlEnabled, true), ); const [showCreateAsModal, setShowCreateAsModal] = useState(false); const [createAs, setCreateAs] = useState(''); From 0db59b45b8ef7af003c7ab4518e4eb63c08f1ff5 Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Thu, 10 Oct 2024 16:46:17 -0400 Subject: [PATCH 08/23] fix: adhoc metrics (#30202) --- superset/connectors/sqla/models.py | 2 + superset/models/helpers.py | 21 +++++++- superset/models/sql_lab.py | 1 + superset/sql_parse.py | 40 +++++---------- tests/integration_tests/datasource_tests.py | 4 ++ .../integration_tests/query_context_tests.py | 7 ++- tests/unit_tests/sql_parse_tests.py | 50 +++++++++++++------ 7 files changed, 80 insertions(+), 45 deletions(-) diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 9215e1545bb21..82980cef161d8 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -1533,6 +1533,7 @@ def adhoc_metric_to_sqla( expression = self._process_sql_expression( expression=metric["sqlExpression"], database_id=self.database_id, + engine=self.database.backend, schema=self.schema, template_processor=template_processor, ) @@ -1566,6 +1567,7 @@ def adhoc_column_to_sqla( # pylint: disable=too-many-locals expression = self._process_sql_expression( expression=col["sqlExpression"], database_id=self.database_id, + engine=self.database.backend, schema=self.schema, template_processor=template_processor, ) diff --git a/superset/models/helpers.py b/superset/models/helpers.py index 4085d3a0aabc7..51808f9a46b31 100644 --- a/superset/models/helpers.py +++ b/superset/models/helpers.py @@ -63,6 +63,7 @@ ColumnNotFoundException, QueryClauseValidationException, QueryObjectValidationError, + SupersetParseError, SupersetSecurityException, ) from superset.extensions import feature_flag_manager @@ -112,6 +113,7 @@ def validate_adhoc_subquery( sql: str, database_id: int, + engine: str, default_schema: str, ) -> str: """ @@ -126,7 +128,12 @@ def validate_adhoc_subquery( """ statements = [] for statement in sqlparse.parse(sql): - if has_table_query(statement): + try: + has_table = has_table_query(str(statement), engine) + except SupersetParseError: + has_table = True + + if has_table: if not is_feature_enabled("ALLOW_ADHOC_SUBQUERY"): raise SupersetSecurityException( SupersetError( @@ -135,7 +142,9 @@ def validate_adhoc_subquery( level=ErrorLevel.ERROR, ) ) + # TODO (betodealmeida): reimplement with sqlglot statement = insert_rls_in_predicate(statement, database_id, default_schema) + statements.append(statement) return ";\n".join(str(statement) for statement in statements) @@ -810,10 +819,11 @@ def get_sqla_row_level_filters( # for datasources of type query return [] - def _process_sql_expression( + def _process_sql_expression( # pylint: disable=too-many-arguments self, expression: Optional[str], database_id: int, + engine: str, schema: str, template_processor: Optional[BaseTemplateProcessor], ) -> Optional[str]: @@ -823,6 +833,7 @@ def _process_sql_expression( expression = validate_adhoc_subquery( expression, database_id, + engine, schema, ) try: @@ -1108,6 +1119,7 @@ def adhoc_metric_to_sqla( expression = self._process_sql_expression( expression=metric["sqlExpression"], database_id=self.database_id, + engine=self.database.backend, schema=self.schema, template_processor=template_processor, ) @@ -1551,6 +1563,7 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma col["sqlExpression"] = self._process_sql_expression( expression=col["sqlExpression"], database_id=self.database_id, + engine=self.database.backend, schema=self.schema, template_processor=template_processor, ) @@ -1613,6 +1626,7 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma selected = validate_adhoc_subquery( selected, self.database_id, + self.database.backend, self.schema, ) outer = literal_column(f"({selected})") @@ -1639,6 +1653,7 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma selected = validate_adhoc_subquery( _sql, self.database_id, + self.database.backend, self.schema, ) @@ -1915,6 +1930,7 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma where = self._process_sql_expression( expression=where, database_id=self.database_id, + engine=self.database.backend, schema=self.schema, template_processor=template_processor, ) @@ -1933,6 +1949,7 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma having = self._process_sql_expression( expression=having, database_id=self.database_id, + engine=self.database.backend, schema=self.schema, template_processor=template_processor, ) diff --git a/superset/models/sql_lab.py b/superset/models/sql_lab.py index 6f25a5a66058c..1702601d0f244 100644 --- a/superset/models/sql_lab.py +++ b/superset/models/sql_lab.py @@ -374,6 +374,7 @@ def adhoc_column_to_sqla( expression = self._process_sql_expression( expression=col["sqlExpression"], database_id=self.database_id, + engine=self.database.backend, schema=self.schema, template_processor=template_processor, ) diff --git a/superset/sql_parse.py b/superset/sql_parse.py index 1581b0c6e79e6..cb457cd4f5c51 100644 --- a/superset/sql_parse.py +++ b/superset/sql_parse.py @@ -64,6 +64,7 @@ extract_tables_from_statement, SQLGLOT_DIALECTS, SQLScript, + SQLStatement, Table, ) from superset.utils.backports import StrEnum @@ -570,46 +571,31 @@ class InsertRLSState(StrEnum): FOUND_TABLE = "FOUND_TABLE" -def has_table_query(token_list: TokenList) -> bool: +def has_table_query(expression: str, engine: str) -> bool: """ Return if a statement has a query reading from a table. - >>> has_table_query(sqlparse.parse("COUNT(*)")[0]) + >>> has_table_query("COUNT(*)", "postgresql") False - >>> has_table_query(sqlparse.parse("SELECT * FROM table")[0]) + >>> has_table_query("SELECT * FROM table", "postgresql") True Note that queries reading from constant values return false: - >>> has_table_query(sqlparse.parse("SELECT * FROM (SELECT 1)")[0]) + >>> has_table_query("SELECT * FROM (SELECT 1)", "postgresql") False """ - state = InsertRLSState.SCANNING - for token in token_list.tokens: - # Ignore comments - if isinstance(token, sqlparse.sql.Comment): - continue - - # Recurse into child token list - if isinstance(token, TokenList) and has_table_query(token): - return True - - # Found a source keyword (FROM/JOIN) - if imt(token, m=[(Keyword, "FROM"), (Keyword, "JOIN")]): - state = InsertRLSState.SEEN_SOURCE - - # Found identifier/keyword after FROM/JOIN - elif state == InsertRLSState.SEEN_SOURCE and ( - isinstance(token, sqlparse.sql.Identifier) or token.ttype == Keyword - ): - return True + # Remove trailing semicolon. + expression = expression.strip().rstrip(";") - # Found nothing, leaving source - elif state == InsertRLSState.SEEN_SOURCE and token.ttype != Whitespace: - state = InsertRLSState.SCANNING + # Wrap the expression in parentheses if it's not already. + if not expression.startswith("("): + expression = f"({expression})" - return False + sql = f"SELECT {expression}" + statement = SQLStatement(sql, engine) + return any(statement.tables) def add_table_name(rls: TokenList, table: str) -> None: diff --git a/tests/integration_tests/datasource_tests.py b/tests/integration_tests/datasource_tests.py index ec45c8c57e882..ab13fc4dafb60 100644 --- a/tests/integration_tests/datasource_tests.py +++ b/tests/integration_tests/datasource_tests.py @@ -42,6 +42,7 @@ get_main_database, ) from tests.integration_tests.base_tests import db_insert_temp_object, SupersetTestCase +from tests.integration_tests.conftest import with_feature_flags from tests.integration_tests.constants import ADMIN_USERNAME from tests.integration_tests.fixtures.birth_names_dashboard import ( load_birth_names_dashboard_with_slices, # noqa: F401 @@ -585,6 +586,7 @@ def test_get_samples_with_incorrect_cc(test_client, login_as_admin, virtual_data assert "INCORRECT SQL" in rv.json.get("error") +@with_feature_flags(ALLOW_ADHOC_SUBQUERY=True) def test_get_samples_on_physical_dataset(test_client, login_as_admin, physical_dataset): uri = ( f"/datasource/samples?datasource_id={physical_dataset.id}&datasource_type=table" @@ -649,6 +651,7 @@ def test_get_samples_with_filters(test_client, login_as_admin, virtual_dataset): assert rv.json["result"]["rowcount"] == 0 +@with_feature_flags(ALLOW_ADHOC_SUBQUERY=True) def test_get_samples_with_time_filter(test_client, login_as_admin, physical_dataset): uri = ( f"/datasource/samples?datasource_id={physical_dataset.id}&datasource_type=table" @@ -669,6 +672,7 @@ def test_get_samples_with_time_filter(test_client, login_as_admin, physical_data assert rv.json["result"]["total_count"] == 2 +@with_feature_flags(ALLOW_ADHOC_SUBQUERY=True) def test_get_samples_with_multiple_filters( test_client, login_as_admin, physical_dataset ): diff --git a/tests/integration_tests/query_context_tests.py b/tests/integration_tests/query_context_tests.py index 4822b690ed84c..d77523c71c9b0 100644 --- a/tests/integration_tests/query_context_tests.py +++ b/tests/integration_tests/query_context_tests.py @@ -42,7 +42,11 @@ ) from superset.utils.pandas_postprocessing.utils import FLAT_COLUMN_SEPARATOR from tests.integration_tests.base_tests import SupersetTestCase -from tests.integration_tests.conftest import only_postgresql, only_sqlite +from tests.integration_tests.conftest import ( + only_postgresql, + only_sqlite, + with_feature_flags, +) from tests.integration_tests.fixtures.birth_names_dashboard import ( load_birth_names_dashboard_with_slices, # noqa: F401 load_birth_names_data, # noqa: F401 @@ -858,6 +862,7 @@ def test_non_time_column_with_time_grain(app_context, physical_dataset): assert df["COL2 ALIAS"][0] == "a" +@with_feature_flags(ALLOW_ADHOC_SUBQUERY=True) def test_special_chars_in_column_name(app_context, physical_dataset): qc = QueryContextFactory().create( datasource={ diff --git a/tests/unit_tests/sql_parse_tests.py b/tests/unit_tests/sql_parse_tests.py index 23d51de64cdeb..44d52c7f6e8fb 100644 --- a/tests/unit_tests/sql_parse_tests.py +++ b/tests/unit_tests/sql_parse_tests.py @@ -1286,46 +1286,66 @@ def test_sqlparse_issue_652(): @pytest.mark.parametrize( - "sql,expected", + ("engine", "sql", "expected"), [ - ("SELECT * FROM table", True), - ("SELECT a FROM (SELECT 1 AS a) JOIN (SELECT * FROM table)", True), - ("(SELECT COUNT(DISTINCT name) AS foo FROM birth_names)", True), - ("COUNT(*)", False), - ("SELECT a FROM (SELECT 1 AS a)", False), - ("SELECT a FROM (SELECT 1 AS a) JOIN table", True), - ("SELECT * FROM (SELECT 1 AS foo, 2 AS bar) ORDER BY foo ASC, bar", False), - ("SELECT * FROM other_table", True), - ("extract(HOUR from from_unixtime(hour_ts)", False), - ("(SELECT * FROM table)", True), - ("(SELECT COUNT(DISTINCT name) from birth_names)", True), + ("postgresql", "extract(HOUR from from_unixtime(hour_ts))", False), + ("postgresql", "SELECT * FROM table", True), + ("postgresql", "(SELECT * FROM table)", True), ( + "postgresql", + "SELECT a FROM (SELECT 1 AS a) JOIN (SELECT * FROM table)", + True, + ), + ( + "postgresql", + "(SELECT COUNT(DISTINCT name) AS foo FROM birth_names)", + True, + ), + ("postgresql", "COUNT(*)", False), + ("postgresql", "SELECT a FROM (SELECT 1 AS a)", False), + ("postgresql", "SELECT a FROM (SELECT 1 AS a) JOIN table", True), + ( + "postgresql", + "SELECT * FROM (SELECT 1 AS foo, 2 AS bar) ORDER BY foo ASC, bar", + False, + ), + ("postgresql", "SELECT * FROM other_table", True), + ("postgresql", "(SELECT COUNT(DISTINCT name) from birth_names)", True), + ( + "postgresql", "(SELECT table_name FROM information_schema.tables WHERE table_name LIKE '%user%' LIMIT 1)", True, ), ( + "postgresql", "(SELECT table_name FROM /**/ information_schema.tables WHERE table_name LIKE '%user%' LIMIT 1)", True, ), ( + "postgresql", "SELECT FROM (SELECT FROM forbidden_table) AS forbidden_table;", True, ), ( + "postgresql", "SELECT * FROM (SELECT * FROM forbidden_table) forbidden_table", True, ), + ( + "postgresql", + "((select users.id from (select 'majorie' as a) b, users where b.a = users.name and users.name in ('majorie') limit 1) like 'U%')", + True, + ), ], ) -def test_has_table_query(sql: str, expected: bool) -> None: +def test_has_table_query(engine: str, sql: str, expected: bool) -> None: """ Test if a given statement queries a table. This is used to prevent ad-hoc metrics from querying unauthorized tables, bypassing row-level security. """ - statement = sqlparse.parse(sql)[0] - assert has_table_query(statement) == expected + assert has_table_query(sql, engine) == expected @pytest.mark.parametrize( From 9c12b1c7dadf461c2cd88e7aa74f15337f9ad599 Mon Sep 17 00:00:00 2001 From: Vitor Avila <96086495+Vitor-Avila@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:03:19 -0300 Subject: [PATCH 09/23] fix(Jinja metric macro): Support Drill By and Excel/CSV download without a dataset ID (#30443) --- superset/jinja_context.py | 44 ++- tests/integration_tests/sqla_models_tests.py | 14 +- tests/unit_tests/jinja_context_test.py | 393 ++++++++++++------- 3 files changed, 284 insertions(+), 167 deletions(-) diff --git a/superset/jinja_context.py b/superset/jinja_context.py index e4a83422315d8..604e26b1dbb36 100644 --- a/superset/jinja_context.py +++ b/superset/jinja_context.py @@ -25,7 +25,7 @@ from typing import Any, Callable, cast, Optional, TYPE_CHECKING, TypedDict, Union import dateutil -from flask import current_app, has_request_context, request +from flask import current_app, g, has_request_context, request from flask_babel import gettext as _ from jinja2 import DebugUndefined, Environment from jinja2.sandbox import SandboxedEnvironment @@ -847,35 +847,45 @@ def dataset_macro( def get_dataset_id_from_context(metric_key: str) -> int: """ - Retrives the Dataset ID from the request context. + Retrieves the Dataset ID from the request context. :param metric_key: the metric key. :returns: the dataset ID. """ # pylint: disable=import-outside-toplevel from superset.daos.chart import ChartDAO - from superset.views.utils import get_form_data + from superset.views.utils import loads_request_json + form_data: dict[str, Any] = {} exc_message = _( "Please specify the Dataset ID for the ``%(name)s`` metric in the Jinja macro.", name=metric_key, ) - form_data, chart = get_form_data() - if not (form_data or chart): - raise SupersetTemplateException(exc_message) + if has_request_context(): + if payload := request.get_json(cache=True) if request.is_json else None: + if dataset_id := payload.get("datasource", {}).get("id"): + return dataset_id + form_data.update(payload.get("form_data", {})) + request_form = loads_request_json(request.form.get("form_data")) + form_data.update(request_form) + request_args = loads_request_json(request.args.get("form_data")) + form_data.update(request_args) + + if form_data := (form_data or getattr(g, "form_data", {})): + if datasource_info := form_data.get("datasource"): + if isinstance(datasource_info, dict): + return datasource_info["id"] + return datasource_info.split("__")[0] + url_params = form_data.get("queries", [{}])[0].get("url_params", {}) + if dataset_id := url_params.get("datasource_id"): + return dataset_id + if chart_id := (form_data.get("slice_id") or url_params.get("slice_id")): + chart_data = ChartDAO.find_by_id(chart_id) + if not chart_data: + raise SupersetTemplateException(exc_message) + return chart_data.datasource_id - if chart and chart.datasource_id: - return chart.datasource_id - if dataset_id := form_data.get("url_params", {}).get("datasource_id"): - return dataset_id - if chart_id := ( - form_data.get("slice_id") or form_data.get("url_params", {}).get("slice_id") - ): - chart_data = ChartDAO.find_by_id(chart_id) - if not chart_data: - raise SupersetTemplateException(exc_message) - return chart_data.datasource_id raise SupersetTemplateException(exc_message) diff --git a/tests/integration_tests/sqla_models_tests.py b/tests/integration_tests/sqla_models_tests.py index 922cbf67fd65e..2d7f6bf041bdd 100644 --- a/tests/integration_tests/sqla_models_tests.py +++ b/tests/integration_tests/sqla_models_tests.py @@ -200,8 +200,8 @@ def test_jinja_metrics_and_calc_columns(self, mock_username): db.session.delete(table) db.session.commit() - @patch("superset.views.utils.get_form_data") - def test_jinja_metric_macro(self, mock_form_data_context): + @patch("superset.jinja_context.get_dataset_id_from_context") + def test_jinja_metric_macro(self, mock_dataset_id_from_context): self.login(username="admin") table = self.get_table(name="birth_names") metric = SqlMetric( @@ -234,14 +234,8 @@ def test_jinja_metric_macro(self, mock_form_data_context): "filter": [], "extras": {"time_grain_sqla": "P1D"}, } - mock_form_data_context.return_value = [ - { - "url_params": { - "datasource_id": table.id, - } - }, - None, - ] + mock_dataset_id_from_context.return_value = table.id + sqla_query = table.get_sqla_query(**base_query_obj) query = table.database.compile_sqla_query(sqla_query.sqla_query) diff --git a/tests/unit_tests/jinja_context_test.py b/tests/unit_tests/jinja_context_test.py index ced40c8119dea..391ead3f46277 100644 --- a/tests/unit_tests/jinja_context_test.py +++ b/tests/unit_tests/jinja_context_test.py @@ -584,15 +584,15 @@ def test_metric_macro_no_dataset_id_no_context(mocker: MockerFixture) -> None: not available in the context. """ DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [None, None] - with pytest.raises(SupersetTemplateException) as excinfo: - metric_macro("macro_key") - assert str(excinfo.value) == ( - "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." - ) - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_not_called() + mock_g = mocker.patch("superset.jinja_context.g") + mock_g.form_data = {} + with app.test_request_context(): + with pytest.raises(SupersetTemplateException) as excinfo: + metric_macro("macro_key") + assert str(excinfo.value) == ( + "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + ) + DatasetDAO.find_by_id.assert_not_called() def test_metric_macro_no_dataset_id_with_context_missing_info( @@ -603,20 +603,31 @@ def test_metric_macro_no_dataset_id_with_context_missing_info( has context but no dataset/chart ID. """ DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [ - { - "url_params": {}, - }, - None, - ] - with pytest.raises(SupersetTemplateException) as excinfo: - metric_macro("macro_key") - assert str(excinfo.value) == ( - "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." - ) - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_not_called() + mock_g = mocker.patch("superset.jinja_context.g") + mock_g.form_data = {"queries": []} + with app.test_request_context( + data={ + "form_data": json.dumps( + { + "adhoc_filters": [ + { + "clause": "WHERE", + "comparator": "foo", + "expressionType": "SIMPLE", + "operator": "in", + "subject": "name", + } + ], + } + ), + } + ): + with pytest.raises(SupersetTemplateException) as excinfo: + metric_macro("macro_key") + assert str(excinfo.value) == ( + "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + ) + DatasetDAO.find_by_id.assert_not_called() def test_metric_macro_no_dataset_id_with_context_datasource_id( @@ -636,18 +647,39 @@ def test_metric_macro_no_dataset_id_with_context_datasource_id( schema="my_schema", sql=None, ) - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [ - { - "url_params": { - "datasource_id": 1, + mock_g = mocker.patch("superset.jinja_context.g") + mock_g.form_data = {} + + # Getting the data from the request context + with app.test_request_context( + data={ + "form_data": json.dumps( + { + "queries": [ + { + "url_params": { + "datasource_id": 1, + } + } + ], + } + ) + } + ): + assert metric_macro("macro_key") == "COUNT(*)" + + # Getting data from g's form_data + mock_g.form_data = { + "queries": [ + { + "url_params": { + "datasource_id": 1, + } } - }, - None, - ] - assert metric_macro("macro_key") == "COUNT(*)" - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_called_once_with(1) + ], + } + with app.test_request_context(): + assert metric_macro("macro_key") == "COUNT(*)" def test_metric_macro_no_dataset_id_with_context_datasource_id_none( @@ -657,26 +689,47 @@ def test_metric_macro_no_dataset_id_with_context_datasource_id_none( Test the ``metric_macro`` when not specifying a dataset ID and it's set to None in the context (url_params.datasource_id). """ - ChartDAO = mocker.patch("superset.daos.chart.ChartDAO") - ChartDAO.find_by_id.return_value = None - DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [ - { - "url_params": { - "datasource_id": None, - } - }, - None, - ] + mock_g = mocker.patch("superset.jinja_context.g") + mock_g.form_data = {} - with pytest.raises(SupersetTemplateException) as excinfo: - metric_macro("macro_key") - assert str(excinfo.value) == ( - "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." - ) - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_not_called() + # Getting the data from the request context + with app.test_request_context( + data={ + "form_data": json.dumps( + { + "queries": [ + { + "url_params": { + "datasource_id": None, + } + } + ], + } + ) + } + ): + with pytest.raises(SupersetTemplateException) as excinfo: + metric_macro("macro_key") + assert str(excinfo.value) == ( + "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + ) + + # Getting data from g's form_data + mock_g.form_data = { + "queries": [ + { + "url_params": { + "datasource_id": None, + } + } + ], + } + with app.test_request_context(): + with pytest.raises(SupersetTemplateException) as excinfo: + metric_macro("macro_key") + assert str(excinfo.value) == ( + "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + ) def test_metric_macro_no_dataset_id_with_context_chart_id( @@ -700,16 +753,40 @@ def test_metric_macro_no_dataset_id_with_context_chart_id( schema="my_schema", sql=None, ) - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [ - { - "slice_id": 1, - }, - None, - ] - assert metric_macro("macro_key") == "COUNT(*)" - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_called_once_with(1) + + mock_g = mocker.patch("superset.jinja_context.g") + mock_g.form_data = {} + + # Getting the data from the request context + with app.test_request_context( + data={ + "form_data": json.dumps( + { + "queries": [ + { + "url_params": { + "slice_id": 1, + } + } + ], + } + ) + } + ): + assert metric_macro("macro_key") == "COUNT(*)" + + # Getting data from g's form_data + mock_g.form_data = { + "queries": [ + { + "url_params": { + "slice_id": 1, + } + } + ], + } + with app.test_request_context(): + assert metric_macro("macro_key") == "COUNT(*)" def test_metric_macro_no_dataset_id_with_context_slice_id_none( @@ -719,53 +796,47 @@ def test_metric_macro_no_dataset_id_with_context_slice_id_none( Test the ``metric_macro`` when not specifying a dataset ID and context includes slice_id set to None (url_params.slice_id). """ - ChartDAO = mocker.patch("superset.daos.chart.ChartDAO") - ChartDAO.find_by_id.return_value = None - DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [ - { - "slice_id": None, - }, - None, - ] - - with pytest.raises(SupersetTemplateException) as excinfo: - metric_macro("macro_key") - assert str(excinfo.value) == ( - "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." - ) - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_not_called() + mock_g = mocker.patch("superset.jinja_context.g") + mock_g.form_data = {} + # Getting the data from the request context + with app.test_request_context( + data={ + "form_data": json.dumps( + { + "queries": [ + { + "url_params": { + "slice_id": None, + } + } + ], + } + ) + } + ): + with pytest.raises(SupersetTemplateException) as excinfo: + metric_macro("macro_key") + assert str(excinfo.value) == ( + "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + ) -def test_metric_macro_no_dataset_id_with_context_chart(mocker: MockerFixture) -> None: - """ - Test the ``metric_macro`` when not specifying a dataset ID and context - includes an existing chart (get_form_data()[1]). - """ - ChartDAO = mocker.patch("superset.daos.chart.ChartDAO") - DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") - DatasetDAO.find_by_id.return_value = SqlaTable( - table_name="test_dataset", - metrics=[ - SqlMetric(metric_name="macro_key", expression="COUNT(*)"), + # Getting data from g's form_data + mock_g.form_data = { + "queries": [ + { + "url_params": { + "slice_id": None, + } + } ], - database=Database(database_name="my_database", sqlalchemy_uri="sqlite://"), - schema="my_schema", - sql=None, - ) - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [ - { - "slice_id": 1, - }, - Slice(datasource_id=1), - ] - assert metric_macro("macro_key") == "COUNT(*)" - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_called_once_with(1) - ChartDAO.find_by_id.assert_not_called() + } + with app.test_request_context(): + with pytest.raises(SupersetTemplateException) as excinfo: + metric_macro("macro_key") + assert str(excinfo.value) == ( + "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + ) def test_metric_macro_no_dataset_id_with_context_deleted_chart( @@ -777,49 +848,91 @@ def test_metric_macro_no_dataset_id_with_context_deleted_chart( """ ChartDAO = mocker.patch("superset.daos.chart.ChartDAO") ChartDAO.find_by_id.return_value = None - DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [ - { - "slice_id": 1, - }, - None, - ] + mock_g = mocker.patch("superset.jinja_context.g") + mock_g.form_data = {} - with pytest.raises(SupersetTemplateException) as excinfo: - metric_macro("macro_key") - assert str(excinfo.value) == ( - "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." - ) - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_not_called() + # Getting the data from the request context + with app.test_request_context( + data={ + "form_data": json.dumps( + { + "queries": [ + { + "url_params": { + "slice_id": 1, + } + } + ], + } + ) + } + ): + with pytest.raises(SupersetTemplateException) as excinfo: + metric_macro("macro_key") + assert str(excinfo.value) == ( + "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + ) + + # Getting data from g's form_data + mock_g.form_data = { + "queries": [ + { + "url_params": { + "slice_id": 1, + } + } + ], + } + with app.test_request_context(): + with pytest.raises(SupersetTemplateException) as excinfo: + metric_macro("macro_key") + assert str(excinfo.value) == ( + "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + ) -def test_metric_macro_no_dataset_id_with_context_chart_no_datasource_id( +def test_metric_macro_no_dataset_id_available_in_request_form_data( mocker: MockerFixture, ) -> None: """ Test the ``metric_macro`` when not specifying a dataset ID and context - includes an existing chart (get_form_data()[1]) with no dataset ID. + includes an existing dataset ID (datasource.id). """ - ChartDAO = mocker.patch("superset.daos.chart.ChartDAO") - ChartDAO.find_by_id.return_value = None DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") - mock_get_form_data = mocker.patch("superset.views.utils.get_form_data") - mock_get_form_data.return_value = [ - {}, - Slice( - datasource_id=None, - ), - ] - - with pytest.raises(SupersetTemplateException) as excinfo: - metric_macro("macro_key") - assert str(excinfo.value) == ( - "Please specify the Dataset ID for the ``macro_key`` metric in the Jinja macro." + DatasetDAO.find_by_id.return_value = SqlaTable( + table_name="test_dataset", + metrics=[ + SqlMetric(metric_name="macro_key", expression="COUNT(*)"), + ], + database=Database(database_name="my_database", sqlalchemy_uri="sqlite://"), + schema="my_schema", + sql=None, ) - mock_get_form_data.assert_called_once() - DatasetDAO.find_by_id.assert_not_called() + + mock_g = mocker.patch("superset.jinja_context.g") + mock_g.form_data = {} + + # Getting the data from the request context + with app.test_request_context( + data={ + "form_data": json.dumps( + { + "datasource": { + "id": 1, + }, + } + ) + } + ): + assert metric_macro("macro_key") == "COUNT(*)" + + # Getting data from g's form_data + mock_g.form_data = { + "datasource": "1__table", + } + + with app.test_request_context(): + assert metric_macro("macro_key") == "COUNT(*)" @pytest.mark.parametrize( From 9a2b1a5cf77fd1a63ec47e50c385169559fbf892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Sat, 12 Oct 2024 01:46:01 +0700 Subject: [PATCH 10/23] chore(fe): uplift FE packages to latest version (#30357) Signed-off-by: hainenber --- superset-frontend/jest.config.js | 2 +- superset-frontend/package-lock.json | 455 ++++++++++-------- superset-frontend/package.json | 8 +- .../superset-ui-chart-controls/package.json | 6 +- .../packages/superset-ui-core/package.json | 38 +- .../test/chart/clients/ChartClient.test.ts | 2 +- .../test/connection/SupersetClient.test.ts | 8 +- .../connection/SupersetClientClass.test.ts | 37 +- .../test/connection/callApi/callApi.test.ts | 78 +-- .../callApiAndParseWithTimeout.test.ts | 13 +- .../connection/callApi/parseResponse.test.ts | 14 +- .../api/legacy/getDatasourceMetadata.test.ts | 4 +- .../test/query/api/legacy/getFormData.test.ts | 4 +- .../test/query/api/setupClientForTest.ts | 1 + .../test/query/api/v1/getChartData.test.ts | 4 +- .../test/query/api/v1/makeApi.test.ts | 4 +- .../time-comparison/fetchTimeRange.test.ts | 20 +- .../package.json | 2 +- .../plugins/plugin-chart-table/package.json | 6 +- .../spec/helpers/testing-library.tsx | 2 +- .../ShareSqlLabQuery.test.tsx | 2 +- .../components/SouthPane/SouthPane.test.tsx | 2 +- .../AlteredSliceTag/AlteredSliceTag.test.jsx | 2 +- .../InvalidSQLErrorMessage.test.tsx | 2 +- .../MarshmallowErrorMessage.test.tsx | 2 +- .../FiltersConfigModal.test.tsx | 4 +- .../tests/CurrentCalendarFrame.test.tsx | 2 +- .../ColumnSelectPopover.test.tsx | 2 +- .../OAuth2ClientField.test.tsx | 2 +- .../databases/DatabaseModal/index.test.tsx | 2 + .../UploadDataModel/UploadDataModal.test.tsx | 6 +- 31 files changed, 402 insertions(+), 334 deletions(-) diff --git a/superset-frontend/jest.config.js b/superset-frontend/jest.config.js index cb1a882869e43..9caf67f166ae6 100644 --- a/superset-frontend/jest.config.js +++ b/superset-frontend/jest.config.js @@ -56,7 +56,7 @@ module.exports = { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], snapshotSerializers: ['@emotion/jest/enzyme-serializer'], transformIgnorePatterns: [ - 'node_modules/(?!d3-(interpolate|color|time)|remark-gfm|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|@rjsf/*.|sinon|echarts|zrender)', + 'node_modules/(?!d3-(interpolate|color|time)|remark-gfm|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|@rjsf/*.|sinon|echarts|zrender|fetch-mock)', ], globals: { __DEV__: true, diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 1c452cb65330e..533829ac9bbc7 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -178,10 +178,10 @@ "@storybook/react-webpack5": "8.1.11", "@svgr/webpack": "^8.1.0", "@testing-library/dom": "^8.20.1", - "@testing-library/jest-dom": "^5.11.6", + "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^5.1.3", - "@testing-library/user-event": "^12.7.0", + "@testing-library/react-hooks": "^8.0.1", + "@testing-library/user-event": "^12.8.3", "@types/classnames": "^2.2.10", "@types/dom-to-image": "^2.6.7", "@types/enzyme": "^3.10.18", @@ -307,7 +307,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.3.3", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", "license": "MIT" }, "node_modules/@ampproject/remapping": { @@ -5897,6 +5899,7 @@ }, "node_modules/@jest/expect-utils": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" @@ -6021,6 +6024,7 @@ }, "node_modules/@jest/schemas": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -6194,6 +6198,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -6210,6 +6215,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, "dependencies": { "@types/istanbul-lib-report": "*" } @@ -9644,6 +9650,7 @@ }, "node_modules/@sinclair/typebox": { "version": "0.27.8", + "dev": true, "license": "MIT" }, "node_modules/@sindresorhus/is": { @@ -12906,23 +12913,21 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", - "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", + "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==", "license": "MIT", "dependencies": { - "@adobe/css-tools": "^4.0.1", - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", + "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", - "lodash": "^4.17.15", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", "redent": "^3.0.0" }, "engines": { - "node": ">=8", + "node": ">=14", "npm": ">=6", "yarn": ">=1" } @@ -12945,6 +12950,12 @@ "node": ">=8" } }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "license": "MIT" + }, "node_modules/@testing-library/react": { "version": "12.1.5", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", @@ -12964,22 +12975,27 @@ } }, "node_modules/@testing-library/react-hooks": { - "version": "5.1.3", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz", + "integrity": "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", - "@types/react": ">=16.9.0", - "@types/react-dom": ">=16.9.0", - "@types/react-test-renderer": ">=16.9.0", - "filter-console": "^0.1.1", "react-error-boundary": "^3.1.0" }, + "engines": { + "node": ">=12" + }, "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0", - "react-test-renderer": ">=16.9.0" + "@types/react": "^16.9.0 || ^17.0.0", + "react": "^16.9.0 || ^17.0.0", + "react-dom": "^16.9.0 || ^17.0.0", + "react-test-renderer": "^16.9.0 || ^17.0.0" }, "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, "react-dom": { "optional": true }, @@ -13003,7 +13019,9 @@ } }, "node_modules/@testing-library/user-event": { - "version": "12.7.0", + "version": "12.8.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.8.3.tgz", + "integrity": "sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5" @@ -13305,6 +13323,7 @@ }, "node_modules/@types/d3-interpolate": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "@types/d3-color": "*" @@ -13471,6 +13490,13 @@ "@types/node": "*" } }, + "node_modules/@types/glob-to-regexp": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@types/glob-to-regexp/-/glob-to-regexp-0.4.4.tgz", + "integrity": "sha512-nDKoaKJYbnn1MZxUY0cA1bPmmgZbg0cTq7Rh13d0KWYNOiKbqoR+2d89SnRPszGh7ROzSwZ/GOjZ4jPbmmZ6Eg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/glob/node_modules/@types/minimatch": { "version": "5.1.2", "dev": true, @@ -13545,10 +13571,12 @@ }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.3", + "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" @@ -13565,6 +13593,7 @@ }, "node_modules/@types/jest": { "version": "29.5.12", + "dev": true, "license": "MIT", "dependencies": { "expect": "^29.0.0", @@ -13573,6 +13602,7 @@ }, "node_modules/@types/jest/node_modules/ansi-styles": { "version": "5.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -13583,6 +13613,7 @@ }, "node_modules/@types/jest/node_modules/pretty-format": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -13595,6 +13626,7 @@ }, "node_modules/@types/jest/node_modules/react-is": { "version": "18.3.1", + "dev": true, "license": "MIT" }, "node_modules/@types/jquery": { @@ -13831,13 +13863,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-test-renderer": { - "version": "17.0.1", - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-transition-group": { "version": "4.4.10", "dev": true, @@ -13918,6 +13943,7 @@ }, "node_modules/@types/rison": { "version": "0.0.9", + "dev": true, "license": "MIT" }, "node_modules/@types/scheduler": { @@ -13926,6 +13952,7 @@ }, "node_modules/@types/seedrandom": { "version": "3.0.8", + "dev": true, "license": "MIT" }, "node_modules/@types/semver": { @@ -14005,13 +14032,6 @@ "version": "1.0.8", "license": "MIT" }, - "node_modules/@types/testing-library__jest-dom": { - "version": "5.9.5", - "license": "MIT", - "dependencies": { - "@types/jest": "*" - } - }, "node_modules/@types/through": { "version": "0.0.33", "license": "MIT", @@ -14125,12 +14145,14 @@ "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { "version": "15.0.0", + "dev": true, "license": "MIT" }, "node_modules/@types/yauzl": { @@ -22364,6 +22386,7 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -25008,6 +25031,7 @@ }, "node_modules/expect": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", @@ -25852,13 +25876,6 @@ "node": ">=0.10.0" } }, - "node_modules/filter-console": { - "version": "0.1.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/filter-obj": { "version": "1.1.0", "license": "MIT", @@ -30672,6 +30689,7 @@ }, "node_modules/jest-diff": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -30685,6 +30703,7 @@ }, "node_modules/jest-diff/node_modules/ansi-styles": { "version": "5.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -30695,6 +30714,7 @@ }, "node_modules/jest-diff/node_modules/pretty-format": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -30707,6 +30727,7 @@ }, "node_modules/jest-diff/node_modules/react-is": { "version": "18.3.1", + "dev": true, "license": "MIT" }, "node_modules/jest-docblock": { @@ -31686,6 +31707,7 @@ }, "node_modules/jest-get-type": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -31878,6 +31900,7 @@ }, "node_modules/jest-matcher-utils": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -31891,6 +31914,7 @@ }, "node_modules/jest-matcher-utils/node_modules/ansi-styles": { "version": "5.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -31901,6 +31925,7 @@ }, "node_modules/jest-matcher-utils/node_modules/pretty-format": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -31913,10 +31938,12 @@ }, "node_modules/jest-matcher-utils/node_modules/react-is": { "version": "18.3.1", + "dev": true, "license": "MIT" }, "node_modules/jest-message-util": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", @@ -31935,10 +31962,12 @@ }, "node_modules/jest-message-util/node_modules/@types/stack-utils": { "version": "2.0.3", + "dev": true, "license": "MIT" }, "node_modules/jest-message-util/node_modules/ansi-styles": { "version": "5.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -31949,6 +31978,7 @@ }, "node_modules/jest-message-util/node_modules/braces": { "version": "3.0.3", + "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -31959,6 +31989,7 @@ }, "node_modules/jest-message-util/node_modules/fill-range": { "version": "7.1.1", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -31969,6 +32000,7 @@ }, "node_modules/jest-message-util/node_modules/is-number": { "version": "7.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -31976,6 +32008,7 @@ }, "node_modules/jest-message-util/node_modules/micromatch": { "version": "4.0.7", + "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -31987,6 +32020,7 @@ }, "node_modules/jest-message-util/node_modules/pretty-format": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -31999,10 +32033,12 @@ }, "node_modules/jest-message-util/node_modules/react-is": { "version": "18.3.1", + "dev": true, "license": "MIT" }, "node_modules/jest-message-util/node_modules/slash": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -32010,6 +32046,7 @@ }, "node_modules/jest-message-util/node_modules/to-regex-range": { "version": "5.0.1", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -32277,6 +32314,7 @@ }, "node_modules/jest-util": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -32292,6 +32330,7 @@ }, "node_modules/jest-util/node_modules/ci-info": { "version": "3.9.0", + "dev": true, "funding": [ { "type": "github", @@ -46572,6 +46611,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regexparam": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-3.0.0.tgz", + "integrity": "sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/regexpu-core": { "version": "5.3.2", "dev": true, @@ -49607,6 +49656,7 @@ }, "node_modules/stack-utils": { "version": "2.0.3", + "dev": true, "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" @@ -49617,6 +49667,7 @@ }, "node_modules/stack-utils/node_modules/escape-string-regexp": { "version": "2.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -55561,10 +55612,10 @@ "@emotion/react": "^11.4.1", "@superset-ui/core": "*", "@testing-library/dom": "^8.20.1", - "@testing-library/jest-dom": "^5.11.6", + "@testing-library/jest-dom": "*", "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^5.0.3", - "@testing-library/user-event": "^12.7.0", + "@testing-library/react-hooks": "*", + "@testing-library/user-event": "*", "ace-builds": "^1.4.14", "antd": "4.10.3", "brace": "^0.11.1", @@ -55580,21 +55631,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.25.6", - "@testing-library/react-hooks": "^5.1.3", - "@types/d3-format": "^1.3.0", - "@types/d3-interpolate": "^3.0.4", - "@types/d3-scale": "^2.1.1", - "@types/d3-time": "^3.0.3", - "@types/d3-time-format": "^4.0.3", - "@types/enzyme": "^3.10.18", - "@types/fetch-mock": "^7.3.8", "@types/json-bigint": "^1.0.4", - "@types/lodash": "^4.17.7", - "@types/math-expression-evaluator": "^1.3.3", - "@types/node": "^22.5.4", - "@types/prop-types": "^15.7.13", - "@types/rison": "0.0.9", - "@types/seedrandom": "^3.0.8", "@vx/responsive": "^0.0.199", "csstype": "^3.1.3", "d3-format": "^1.3.2", @@ -55604,7 +55641,7 @@ "d3-time-format": "^4.1.0", "fetch-retry": "^6.0.0", "jed": "^1.1.1", - "lodash": "^4.17.11", + "lodash": "^4.17.21", "math-expression-evaluator": "^1.3.8", "pretty-ms": "^7.0.0", "react-error-boundary": "^1.2.5", @@ -55620,8 +55657,21 @@ }, "devDependencies": { "@emotion/styled": "^11.3.0", - "fetch-mock": "^6.5.2", - "jest-mock-console": "^1.0.0", + "@types/d3-format": "^1.3.0", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-scale": "^2.1.1", + "@types/d3-time": "^3.0.3", + "@types/d3-time-format": "^4.0.3", + "@types/enzyme": "^3.10.18", + "@types/fetch-mock": "^7.3.8", + "@types/lodash": "^4.17.7", + "@types/math-expression-evaluator": "^1.3.3", + "@types/node": "^22.5.4", + "@types/prop-types": "^15.7.2", + "@types/rison": "0.0.9", + "@types/seedrandom": "^3.0.8", + "fetch-mock": "^11.1.4", + "jest-mock-console": "^2.0.0", "resize-observer-polyfill": "1.5.1", "timezone-mock": "1.3.6" }, @@ -55630,9 +55680,10 @@ "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "@testing-library/dom": "^8.20.1", - "@testing-library/jest-dom": "^5.11.6", + "@testing-library/jest-dom": "*", "@testing-library/react": "^12.1.5", - "@testing-library/user-event": "^12.7.0", + "@testing-library/react-hooks": "*", + "@testing-library/user-event": "*", "@types/react": "*", "@types/react-loadable": "*", "@types/tinycolor2": "*", @@ -55652,70 +55703,34 @@ "node": ">=6.9.0" } }, - "packages/superset-ui-core/node_modules/@testing-library/react-hooks": { - "version": "8.0.1", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5", - "react-error-boundary": "^3.1.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0", - "react": "^16.9.0 || ^17.0.0", - "react-dom": "^16.9.0 || ^17.0.0", - "react-test-renderer": "^16.9.0 || ^17.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "react-test-renderer": { - "optional": true - } - } - }, - "packages/superset-ui-core/node_modules/@testing-library/react-hooks/node_modules/react-error-boundary": { - "version": "3.1.4", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "react": ">=16.13.1" - } - }, "packages/superset-ui-core/node_modules/@types/d3-format": { "version": "1.4.2", + "dev": true, "license": "MIT" }, "packages/superset-ui-core/node_modules/@types/d3-time": { "version": "3.0.3", + "dev": true, "license": "MIT" }, "packages/superset-ui-core/node_modules/@types/d3-time-format": { "version": "2.3.1", + "dev": true, "license": "MIT" }, "packages/superset-ui-core/node_modules/@types/fetch-mock": { "version": "7.3.8", + "dev": true, "license": "MIT" }, "packages/superset-ui-core/node_modules/@types/lodash": { "version": "4.17.7", + "dev": true, "license": "MIT" }, "packages/superset-ui-core/node_modules/@types/math-expression-evaluator": { "version": "1.3.3", + "dev": true, "license": "MIT" }, "packages/superset-ui-core/node_modules/d3-array": { @@ -55785,17 +55800,25 @@ } }, "packages/superset-ui-core/node_modules/fetch-mock": { - "version": "6.5.2", + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-11.1.4.tgz", + "integrity": "sha512-Enndh1ApARgYDPfWFgfzLeSgdQVasMj6qDWDArya6quj3Z83AVGsl1YrVe8OxWVWsN7a+56RQRoGNmo9HdldAg==", "dev": true, - "hasInstallScript": true, "license": "MIT", "dependencies": { - "babel-polyfill": "^6.26.0", - "glob-to-regexp": "^0.4.0", - "path-to-regexp": "^2.2.1" + "@types/glob-to-regexp": "^0.4.4", + "dequal": "^2.0.3", + "glob-to-regexp": "^0.4.1", + "is-subset": "^0.1.1", + "regexparam": "^3.0.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=8.0.0" + }, + "peerDependenciesMeta": { + "node-fetch": { + "optional": true + } } }, "packages/superset-ui-core/node_modules/jest-mock-console": { @@ -57232,7 +57255,7 @@ "peerDependencies": { "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "@testing-library/jest-dom": "^5.17.0", + "@testing-library/jest-dom": "*", "@testing-library/react": "^12.1.5", "react": "^16.13.1", "react-dom": "^16.13.1" @@ -57864,10 +57887,10 @@ "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", "@testing-library/dom": "^8.20.1", - "@testing-library/jest-dom": "^5.11.6", + "@testing-library/jest-dom": "*", "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^5.0.3", - "@testing-library/user-event": "^12.7.0", + "@testing-library/react-hooks": "*", + "@testing-library/user-event": "*", "@types/classnames": "*", "@types/react": "*", "match-sorter": "^6.3.3", @@ -58007,7 +58030,9 @@ "dev": true }, "@adobe/css-tools": { - "version": "4.3.3" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==" }, "@ampproject/remapping": { "version": "2.2.0", @@ -61608,6 +61633,7 @@ }, "@jest/expect-utils": { "version": "29.7.0", + "dev": true, "requires": { "jest-get-type": "^29.6.3" } @@ -61696,6 +61722,7 @@ }, "@jest/schemas": { "version": "29.6.3", + "dev": true, "requires": { "@sinclair/typebox": "^0.27.8" } @@ -61829,6 +61856,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, "requires": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -61842,6 +61870,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, "requires": { "@types/istanbul-lib-report": "*" } @@ -64221,7 +64250,8 @@ } }, "@sinclair/typebox": { - "version": "0.27.8" + "version": "0.27.8", + "dev": true }, "@sindresorhus/is": { "version": "4.6.0", @@ -65809,7 +65839,6 @@ "requires": { "@babel/runtime": "^7.25.6", "@emotion/styled": "^11.3.0", - "@testing-library/react-hooks": "^5.1.3", "@types/d3-format": "^1.3.0", "@types/d3-interpolate": "^3.0.4", "@types/d3-scale": "^2.1.1", @@ -65821,7 +65850,7 @@ "@types/lodash": "^4.17.7", "@types/math-expression-evaluator": "^1.3.3", "@types/node": "^22.5.4", - "@types/prop-types": "^15.7.13", + "@types/prop-types": "^15.7.2", "@types/rison": "0.0.9", "@types/seedrandom": "^3.0.8", "@vx/responsive": "^0.0.199", @@ -65831,11 +65860,11 @@ "d3-scale": "^3.0.0", "d3-time": "^3.1.0", "d3-time-format": "^4.1.0", - "fetch-mock": "^6.5.2", + "fetch-mock": "^11.1.4", "fetch-retry": "^6.0.0", "jed": "^1.1.1", - "jest-mock-console": "^1.0.0", - "lodash": "^4.17.11", + "jest-mock-console": "^2.0.0", + "lodash": "^4.17.21", "math-expression-evaluator": "^1.3.8", "pretty-ms": "^7.0.0", "react-error-boundary": "^1.2.5", @@ -65860,38 +65889,29 @@ "regenerator-runtime": "^0.14.0" } }, - "@testing-library/react-hooks": { - "version": "8.0.1", - "requires": { - "@babel/runtime": "^7.12.5", - "react-error-boundary": "^3.1.0" - }, - "dependencies": { - "react-error-boundary": { - "version": "3.1.4", - "requires": { - "@babel/runtime": "^7.12.5" - } - } - } - }, "@types/d3-format": { - "version": "1.4.2" + "version": "1.4.2", + "dev": true }, "@types/d3-time": { - "version": "3.0.3" + "version": "3.0.3", + "dev": true }, "@types/d3-time-format": { - "version": "2.3.1" + "version": "2.3.1", + "dev": true }, "@types/fetch-mock": { - "version": "7.3.8" + "version": "7.3.8", + "dev": true }, "@types/lodash": { - "version": "4.17.7" + "version": "4.17.7", + "dev": true }, "@types/math-expression-evaluator": { - "version": "1.3.3" + "version": "1.3.3", + "dev": true }, "d3-array": { "version": "2.12.1", @@ -65946,12 +65966,16 @@ "version": "5.0.0" }, "fetch-mock": { - "version": "6.5.2", + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-11.1.4.tgz", + "integrity": "sha512-Enndh1ApARgYDPfWFgfzLeSgdQVasMj6qDWDArya6quj3Z83AVGsl1YrVe8OxWVWsN7a+56RQRoGNmo9HdldAg==", "dev": true, "requires": { - "babel-polyfill": "^6.26.0", - "glob-to-regexp": "^0.4.0", - "path-to-regexp": "^2.2.1" + "@types/glob-to-regexp": "^0.4.4", + "dequal": "^2.0.3", + "glob-to-regexp": "^0.4.1", + "is-subset": "^0.1.1", + "regexparam": "^3.0.0" } }, "jest-mock-console": { @@ -68603,18 +68627,16 @@ } }, "@testing-library/jest-dom": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", - "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", + "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==", "requires": { - "@adobe/css-tools": "^4.0.1", - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", + "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", - "lodash": "^4.17.15", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", "redent": "^3.0.0" }, "dependencies": { @@ -68630,6 +68652,11 @@ "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } + }, + "dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==" } } }, @@ -68644,13 +68671,11 @@ } }, "@testing-library/react-hooks": { - "version": "5.1.3", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz", + "integrity": "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==", "requires": { "@babel/runtime": "^7.12.5", - "@types/react": "^16.9.53", - "@types/react-dom": ">=16.9.0", - "@types/react-test-renderer": ">=16.9.0", - "filter-console": "^0.1.1", "react-error-boundary": "^3.1.0" }, "dependencies": { @@ -68663,7 +68688,9 @@ } }, "@testing-library/user-event": { - "version": "12.7.0", + "version": "12.8.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.8.3.tgz", + "integrity": "sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ==", "requires": { "@babel/runtime": "^7.12.5" } @@ -68914,6 +68941,7 @@ }, "@types/d3-interpolate": { "version": "3.0.4", + "dev": true, "requires": { "@types/d3-color": "*" } @@ -69060,6 +69088,12 @@ } } }, + "@types/glob-to-regexp": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@types/glob-to-regexp/-/glob-to-regexp-0.4.4.tgz", + "integrity": "sha512-nDKoaKJYbnn1MZxUY0cA1bPmmgZbg0cTq7Rh13d0KWYNOiKbqoR+2d89SnRPszGh7ROzSwZ/GOjZ4jPbmmZ6Eg==", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.3", "dev": true, @@ -69119,10 +69153,12 @@ } }, "@types/istanbul-lib-coverage": { - "version": "2.0.3" + "version": "2.0.3", + "dev": true }, "@types/istanbul-lib-report": { "version": "3.0.0", + "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" } @@ -69137,16 +69173,19 @@ }, "@types/jest": { "version": "29.5.12", + "dev": true, "requires": { "expect": "^29.0.0", "pretty-format": "^29.0.0" }, "dependencies": { "ansi-styles": { - "version": "5.2.0" + "version": "5.2.0", + "dev": true }, "pretty-format": { "version": "29.7.0", + "dev": true, "requires": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -69154,7 +69193,8 @@ } }, "react-is": { - "version": "18.3.1" + "version": "18.3.1", + "dev": true } } }, @@ -69362,12 +69402,6 @@ "@types/react": "^16.9.53" } }, - "@types/react-test-renderer": { - "version": "17.0.1", - "requires": { - "@types/react": "^16.9.53" - } - }, "@types/react-transition-group": { "version": "4.4.10", "dev": true, @@ -69440,13 +69474,15 @@ "dev": true }, "@types/rison": { - "version": "0.0.9" + "version": "0.0.9", + "dev": true }, "@types/scheduler": { "version": "0.16.6" }, "@types/seedrandom": { - "version": "3.0.8" + "version": "3.0.8", + "dev": true }, "@types/semver": { "version": "7.5.0", @@ -69516,12 +69552,6 @@ "@types/tapable": { "version": "1.0.8" }, - "@types/testing-library__jest-dom": { - "version": "5.9.5", - "requires": { - "@types/jest": "*" - } - }, "@types/through": { "version": "0.0.33", "requires": { @@ -69610,12 +69640,14 @@ "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "15.0.0" + "version": "15.0.0", + "dev": true }, "@types/yauzl": { "version": "2.9.2", @@ -75124,7 +75156,8 @@ "version": "1.0.5" }, "diff-sequences": { - "version": "29.6.3" + "version": "29.6.3", + "dev": true }, "dir-glob": { "version": "3.0.1", @@ -76833,6 +76866,7 @@ }, "expect": { "version": "29.7.0", + "dev": true, "requires": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", @@ -77404,9 +77438,6 @@ "to-regex-range": "^2.1.0" } }, - "filter-console": { - "version": "0.1.1" - }, "filter-obj": { "version": "1.1.0" }, @@ -80414,6 +80445,7 @@ }, "jest-diff": { "version": "29.7.0", + "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", @@ -80422,10 +80454,12 @@ }, "dependencies": { "ansi-styles": { - "version": "5.2.0" + "version": "5.2.0", + "dev": true }, "pretty-format": { "version": "29.7.0", + "dev": true, "requires": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -80433,7 +80467,8 @@ } }, "react-is": { - "version": "18.3.1" + "version": "18.3.1", + "dev": true } } }, @@ -81100,7 +81135,8 @@ } }, "jest-get-type": { - "version": "29.6.3" + "version": "29.6.3", + "dev": true }, "jest-haste-map": { "version": "29.7.0", @@ -81234,6 +81270,7 @@ }, "jest-matcher-utils": { "version": "29.7.0", + "dev": true, "requires": { "chalk": "^4.0.0", "jest-diff": "^29.7.0", @@ -81242,10 +81279,12 @@ }, "dependencies": { "ansi-styles": { - "version": "5.2.0" + "version": "5.2.0", + "dev": true }, "pretty-format": { "version": "29.7.0", + "dev": true, "requires": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -81253,12 +81292,14 @@ } }, "react-is": { - "version": "18.3.1" + "version": "18.3.1", + "dev": true } } }, "jest-message-util": { "version": "29.7.0", + "dev": true, "requires": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", @@ -81272,28 +81313,34 @@ }, "dependencies": { "@types/stack-utils": { - "version": "2.0.3" + "version": "2.0.3", + "dev": true }, "ansi-styles": { - "version": "5.2.0" + "version": "5.2.0", + "dev": true }, "braces": { "version": "3.0.3", + "dev": true, "requires": { "fill-range": "^7.1.1" } }, "fill-range": { "version": "7.1.1", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, "is-number": { - "version": "7.0.0" + "version": "7.0.0", + "dev": true }, "micromatch": { "version": "4.0.7", + "dev": true, "requires": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -81301,6 +81348,7 @@ }, "pretty-format": { "version": "29.7.0", + "dev": true, "requires": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -81308,13 +81356,16 @@ } }, "react-is": { - "version": "18.3.1" + "version": "18.3.1", + "dev": true }, "slash": { - "version": "3.0.0" + "version": "3.0.0", + "dev": true }, "to-regex-range": { "version": "5.0.1", + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -81507,6 +81558,7 @@ }, "jest-util": { "version": "29.7.0", + "dev": true, "requires": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -81517,7 +81569,8 @@ }, "dependencies": { "ci-info": { - "version": "3.9.0" + "version": "3.9.0", + "dev": true } } }, @@ -90122,6 +90175,12 @@ "set-function-name": "^2.0.1" } }, + "regexparam": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-3.0.0.tgz", + "integrity": "sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==", + "dev": true + }, "regexpu-core": { "version": "5.3.2", "dev": true, @@ -92070,12 +92129,14 @@ }, "stack-utils": { "version": "2.0.3", + "dev": true, "requires": { "escape-string-regexp": "^2.0.0" }, "dependencies": { "escape-string-regexp": { - "version": "2.0.0" + "version": "2.0.0", + "dev": true } } }, diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 3dee70e069fda..258738112ce03 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -244,10 +244,10 @@ "@storybook/react-webpack5": "8.1.11", "@svgr/webpack": "^8.1.0", "@testing-library/dom": "^8.20.1", - "@testing-library/jest-dom": "^5.11.6", + "@testing-library/jest-dom": "^6.5.0", "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^5.1.3", - "@testing-library/user-event": "^12.7.0", + "@testing-library/react-hooks": "^8.0.1", + "@testing-library/user-event": "^12.8.3", "@types/classnames": "^2.2.10", "@types/dom-to-image": "^2.6.7", "@types/enzyme": "^3.10.18", @@ -340,7 +340,7 @@ "react-resizable": "^3.0.5", "react-test-renderer": "^16.14.0", "redux-mock-store": "^1.5.4", - "sinon": "^18.0.1", + "sinon": "^18.0.0", "source-map": "^0.7.4", "source-map-support": "^0.5.21", "speed-measure-webpack-plugin": "^1.5.0", diff --git a/superset-frontend/packages/superset-ui-chart-controls/package.json b/superset-frontend/packages/superset-ui-chart-controls/package.json index c7ce78a603f91..3c4dc88debf50 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/package.json +++ b/superset-frontend/packages/superset-ui-chart-controls/package.json @@ -35,10 +35,10 @@ "@emotion/react": "^11.4.1", "@superset-ui/core": "*", "@testing-library/dom": "^8.20.1", - "@testing-library/jest-dom": "^5.11.6", + "@testing-library/jest-dom": "*", "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^5.0.3", - "@testing-library/user-event": "^12.7.0", + "@testing-library/react-hooks": "*", + "@testing-library/user-event": "*", "ace-builds": "^1.4.14", "antd": "4.10.3", "brace": "^0.11.1", diff --git a/superset-frontend/packages/superset-ui-core/package.json b/superset-frontend/packages/superset-ui-core/package.json index 27b0c6e089355..e532c0e87a5d0 100644 --- a/superset-frontend/packages/superset-ui-core/package.json +++ b/superset-frontend/packages/superset-ui-core/package.json @@ -25,21 +25,7 @@ ], "dependencies": { "@babel/runtime": "^7.25.6", - "@testing-library/react-hooks": "^5.1.3", - "@types/d3-format": "^1.3.0", - "@types/d3-interpolate": "^3.0.4", - "@types/d3-scale": "^2.1.1", - "@types/d3-time": "^3.0.3", - "@types/d3-time-format": "^4.0.3", - "@types/enzyme": "^3.10.18", - "@types/fetch-mock": "^7.3.8", "@types/json-bigint": "^1.0.4", - "@types/lodash": "^4.17.7", - "@types/math-expression-evaluator": "^1.3.3", - "@types/node": "^22.5.4", - "@types/prop-types": "^15.7.13", - "@types/rison": "0.0.9", - "@types/seedrandom": "^3.0.8", "@vx/responsive": "^0.0.199", "csstype": "^3.1.3", "d3-format": "^1.3.2", @@ -49,7 +35,7 @@ "d3-time-format": "^4.1.0", "fetch-retry": "^6.0.0", "jed": "^1.1.1", - "lodash": "^4.17.11", + "lodash": "^4.17.21", "math-expression-evaluator": "^1.3.8", "pretty-ms": "^7.0.0", "react-error-boundary": "^1.2.5", @@ -65,8 +51,21 @@ }, "devDependencies": { "@emotion/styled": "^11.3.0", - "fetch-mock": "^6.5.2", - "jest-mock-console": "^1.0.0", + "@types/d3-format": "^1.3.0", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-scale": "^2.1.1", + "@types/d3-time": "^3.0.3", + "@types/d3-time-format": "^4.0.3", + "@types/enzyme": "^3.10.18", + "@types/fetch-mock": "^7.3.8", + "@types/lodash": "^4.17.7", + "@types/math-expression-evaluator": "^1.3.3", + "@types/node": "^22.5.4", + "@types/prop-types": "^15.7.2", + "@types/rison": "0.0.9", + "@types/seedrandom": "^3.0.8", + "fetch-mock": "^11.1.4", + "jest-mock-console": "^2.0.0", "resize-observer-polyfill": "1.5.1", "timezone-mock": "1.3.6" }, @@ -75,9 +74,10 @@ "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "@testing-library/dom": "^8.20.1", - "@testing-library/jest-dom": "^5.11.6", + "@testing-library/jest-dom": "*", "@testing-library/react": "^12.1.5", - "@testing-library/user-event": "^12.7.0", + "@testing-library/react-hooks": "*", + "@testing-library/user-event": "*", "@types/react": "*", "@types/react-loadable": "*", "@types/tinycolor2": "*", diff --git a/superset-frontend/packages/superset-ui-core/test/chart/clients/ChartClient.test.ts b/superset-frontend/packages/superset-ui-core/test/chart/clients/ChartClient.test.ts index 9992ca9381853..c82755374d3e7 100644 --- a/superset-frontend/packages/superset-ui-core/test/chart/clients/ChartClient.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/chart/clients/ChartClient.test.ts @@ -49,7 +49,7 @@ describe('ChartClient', () => { chartClient = new ChartClient(); }); - afterEach(fetchMock.restore); + afterEach(() => fetchMock.restore()); describe('new ChartClient(config)', () => { it('creates a client without argument', () => { diff --git a/superset-frontend/packages/superset-ui-core/test/connection/SupersetClient.test.ts b/superset-frontend/packages/superset-ui-core/test/connection/SupersetClient.test.ts index caba59f563722..500c7d956401b 100644 --- a/superset-frontend/packages/superset-ui-core/test/connection/SupersetClient.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/connection/SupersetClient.test.ts @@ -22,13 +22,11 @@ import { SupersetClient, SupersetClientClass } from '@superset-ui/core'; import { LOGIN_GLOB } from './fixtures/constants'; describe('SupersetClient', () => { - beforeAll(() => { - fetchMock.get(LOGIN_GLOB, { result: '' }); - }); + beforeAll(() => fetchMock.get(LOGIN_GLOB, { result: '' })); - afterAll(fetchMock.restore); + afterAll(() => fetchMock.restore()); - afterEach(SupersetClient.reset); + afterEach(() => SupersetClient.reset()); it('exposes reset, configure, init, get, post, postForm, isAuthenticated, and reAuthenticate methods', () => { expect(typeof SupersetClient.configure).toBe('function'); diff --git a/superset-frontend/packages/superset-ui-core/test/connection/SupersetClientClass.test.ts b/superset-frontend/packages/superset-ui-core/test/connection/SupersetClientClass.test.ts index 56ab3f1baea07..39f148f7beeec 100644 --- a/superset-frontend/packages/superset-ui-core/test/connection/SupersetClientClass.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/connection/SupersetClientClass.test.ts @@ -21,11 +21,12 @@ import { SupersetClientClass, ClientConfig, CallApi } from '@superset-ui/core'; import { LOGIN_GLOB } from './fixtures/constants'; describe('SupersetClientClass', () => { - beforeAll(() => { + beforeEach(() => { + fetchMock.reset(); fetchMock.get(LOGIN_GLOB, { result: '' }); }); - afterAll(fetchMock.restore); + afterAll(() => fetchMock.restore()); describe('new SupersetClientClass()', () => { it('fallback protocol to https when setting only host', () => { @@ -78,11 +79,10 @@ describe('SupersetClientClass', () => { }); describe('.init()', () => { - afterEach(() => { - fetchMock.reset(); - // reset - fetchMock.get(LOGIN_GLOB, { result: 1234 }, { overwriteRoutes: true }); - }); + beforeEach(() => + fetchMock.get(LOGIN_GLOB, { result: 1234 }, { overwriteRoutes: true }), + ); + afterEach(() => fetchMock.reset()); it('calls api/v1/security/csrf_token/ when init() is called if no CSRF token is passed', async () => { expect.assertions(1); @@ -165,7 +165,7 @@ describe('SupersetClientClass', () => { }); describe('.isAuthenticated()', () => { - afterEach(fetchMock.reset); + afterEach(() => fetchMock.reset()); it('returns true if there is a token and false if not', async () => { expect.assertions(2); @@ -254,7 +254,8 @@ describe('SupersetClientClass', () => { }); describe('requests', () => { - afterEach(fetchMock.reset); + afterEach(() => fetchMock.restore()); + const protocol = 'https:'; const host = 'host'; const mockGetEndpoint = '/get/url'; @@ -272,13 +273,15 @@ describe('SupersetClientClass', () => { const mockTextJsonResponse = '{ "value": 9223372036854775807 }'; const mockPayload = { json: () => Promise.resolve('payload') }; - fetchMock.get(mockGetUrl, mockPayload); - fetchMock.post(mockPostUrl, mockPayload); - fetchMock.put(mockPutUrl, mockPayload); - fetchMock.delete(mockDeleteUrl, mockPayload); - fetchMock.delete(mockRequestUrl, mockPayload); - fetchMock.get(mockTextUrl, mockTextJsonResponse); - fetchMock.post(mockTextUrl, mockTextJsonResponse); + beforeEach(() => { + fetchMock.get(mockGetUrl, mockPayload); + fetchMock.post(mockPostUrl, mockPayload); + fetchMock.put(mockPutUrl, mockPayload); + fetchMock.delete(mockDeleteUrl, mockPayload); + fetchMock.delete(mockRequestUrl, mockPayload); + fetchMock.get(mockTextUrl, mockTextJsonResponse); + fetchMock.post(mockTextUrl, mockTextJsonResponse); + }); it('checks for authentication before every get and post request', async () => { expect.assertions(6); @@ -623,6 +626,8 @@ describe('SupersetClientClass', () => { let createElement: any; beforeEach(async () => { + fetchMock.get(LOGIN_GLOB, { result: 1234 }, { overwriteRoutes: true }); + client = new SupersetClientClass({ protocol, host }); authSpy = jest.spyOn(SupersetClientClass.prototype, 'ensureAuth'); await client.init(); diff --git a/superset-frontend/packages/superset-ui-core/test/connection/callApi/callApi.test.ts b/superset-frontend/packages/superset-ui-core/test/connection/callApi/callApi.test.ts index 1067945a7677f..387b96575be5b 100644 --- a/superset-frontend/packages/superset-ui-core/test/connection/callApi/callApi.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/connection/callApi/callApi.test.ts @@ -29,43 +29,41 @@ const corruptObject = new BadObject(); /* @ts-expect-error */ BadObject.prototype.toString = undefined; +const mockGetUrl = '/mock/get/url'; +const mockPostUrl = '/mock/post/url'; +const mockPutUrl = '/mock/put/url'; +const mockPatchUrl = '/mock/patch/url'; +const mockCacheUrl = '/mock/cache/url'; +const mockNotFound = '/mock/notfound'; +const mockErrorUrl = '/mock/error/url'; +const mock503 = '/mock/503'; + +const mockGetPayload = { get: 'payload' }; +const mockPostPayload = { post: 'payload' }; +const mockPutPayload = { post: 'payload' }; +const mockPatchPayload = { post: 'payload' }; +const mockCachePayload = { + status: 200, + body: 'BODY', + headers: { Etag: 'etag' }, +}; +const mockErrorPayload = { status: 500, statusText: 'Internal error' }; + describe('callApi()', () => { - beforeAll(() => { - fetchMock.get(LOGIN_GLOB, { result: '1234' }); + beforeAll(() => fetchMock.get(LOGIN_GLOB, { result: '1234' })); + + beforeEach(() => { + fetchMock.get(mockGetUrl, mockGetPayload); + fetchMock.post(mockPostUrl, mockPostPayload); + fetchMock.put(mockPutUrl, mockPutPayload); + fetchMock.patch(mockPatchUrl, mockPatchPayload); + fetchMock.get(mockCacheUrl, mockCachePayload); + fetchMock.get(mockNotFound, { status: 404 }); + fetchMock.get(mock503, { status: 503 }); + fetchMock.get(mockErrorUrl, () => Promise.reject(mockErrorPayload)); }); - afterAll(fetchMock.restore); - - const mockGetUrl = '/mock/get/url'; - const mockPostUrl = '/mock/post/url'; - const mockPutUrl = '/mock/put/url'; - const mockPatchUrl = '/mock/patch/url'; - const mockCacheUrl = '/mock/cache/url'; - const mockNotFound = '/mock/notfound'; - const mockErrorUrl = '/mock/error/url'; - const mock503 = '/mock/503'; - - const mockGetPayload = { get: 'payload' }; - const mockPostPayload = { post: 'payload' }; - const mockPutPayload = { post: 'payload' }; - const mockPatchPayload = { post: 'payload' }; - const mockCachePayload = { - status: 200, - body: 'BODY', - headers: { Etag: 'etag' }, - }; - const mockErrorPayload = { status: 500, statusText: 'Internal error' }; - - fetchMock.get(mockGetUrl, mockGetPayload); - fetchMock.post(mockPostUrl, mockPostPayload); - fetchMock.put(mockPutUrl, mockPutPayload); - fetchMock.patch(mockPatchUrl, mockPatchPayload); - fetchMock.get(mockCacheUrl, mockCachePayload); - fetchMock.get(mockNotFound, { status: 404 }); - fetchMock.get(mock503, { status: 503 }); - fetchMock.get(mockErrorUrl, () => Promise.reject(mockErrorPayload)); - - afterEach(fetchMock.reset); + afterEach(() => fetchMock.reset()); describe('request config', () => { it('calls the right url with the specified method', async () => { @@ -401,7 +399,7 @@ describe('callApi()', () => { Object.defineProperty(constants, 'CACHE_AVAILABLE', { value: false }); const firstResponse = await callApi({ url: mockCacheUrl, method: 'GET' }); - const calls = fetchMock.calls(mockCacheUrl); + let calls = fetchMock.calls(mockCacheUrl); expect(calls).toHaveLength(1); const firstBody = await firstResponse.text(); expect(firstBody).toEqual('BODY'); @@ -410,6 +408,7 @@ describe('callApi()', () => { url: mockCacheUrl, method: 'GET', }); + calls = fetchMock.calls(mockCacheUrl); const fetchParams = calls[1][1] as RequestInit; expect(calls).toHaveLength(2); // second call should not have If-None-Match header @@ -425,11 +424,12 @@ describe('callApi()', () => { expect.assertions(3); // first call sets the cache await callApi({ url: mockCacheUrl, method: 'GET' }); - const calls = fetchMock.calls(mockCacheUrl); + let calls = fetchMock.calls(mockCacheUrl); expect(calls).toHaveLength(1); // second call sends the Etag in the If-None-Match header await callApi({ url: mockCacheUrl, method: 'GET' }); + calls = fetchMock.calls(mockCacheUrl); const fetchParams = calls[1][1] as RequestInit; const headers = { 'If-None-Match': 'etag' }; expect(calls).toHaveLength(2); @@ -442,8 +442,7 @@ describe('callApi()', () => { expect.assertions(3); // first call sets the cache await callApi({ url: mockCacheUrl, method: 'GET' }); - const calls = fetchMock.calls(mockCacheUrl); - expect(calls).toHaveLength(1); + expect(fetchMock.calls(mockCacheUrl)).toHaveLength(1); // second call reuses the cached payload on a 304 const mockCachedPayload = { status: 304 }; fetchMock.get(mockCacheUrl, mockCachedPayload, { overwriteRoutes: true }); @@ -452,7 +451,7 @@ describe('callApi()', () => { url: mockCacheUrl, method: 'GET', }); - expect(calls).toHaveLength(2); + expect(fetchMock.calls(mockCacheUrl)).toHaveLength(2); const secondBody = await secondResponse.text(); expect(secondBody).toEqual('BODY'); }); @@ -641,6 +640,7 @@ describe('callApi()', () => { it('should ignore "null" postPayload string', async () => { expect.assertions(1); fetchMock.post('/post-null-postpayload', {}); + fetchMock.post('/post-formdata', {}); await callApi({ url: '/post-formdata', method: 'POST', diff --git a/superset-frontend/packages/superset-ui-core/test/connection/callApi/callApiAndParseWithTimeout.test.ts b/superset-frontend/packages/superset-ui-core/test/connection/callApi/callApiAndParseWithTimeout.test.ts index 36cc95bfa10c6..e0bf14e6c8ee8 100644 --- a/superset-frontend/packages/superset-ui-core/test/connection/callApi/callApiAndParseWithTimeout.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/connection/callApi/callApiAndParseWithTimeout.test.ts @@ -27,16 +27,15 @@ import * as rejectAfterTimeout from '../../../src/connection/callApi/rejectAfter import { LOGIN_GLOB } from '../fixtures/constants'; +const mockGetUrl = '/mock/get/url'; +const mockGetPayload = { get: 'payload' }; + describe('callApiAndParseWithTimeout()', () => { - beforeAll(() => { - fetchMock.get(LOGIN_GLOB, { result: '1234' }); - }); + beforeAll(() => fetchMock.get(LOGIN_GLOB, { result: '1234' })); - afterAll(fetchMock.restore); + beforeEach(() => fetchMock.get(mockGetUrl, mockGetPayload)); - const mockGetUrl = '/mock/get/url'; - const mockGetPayload = { get: 'payload' }; - fetchMock.get(mockGetUrl, mockGetPayload); + afterAll(() => fetchMock.restore()); afterEach(() => { fetchMock.reset(); diff --git a/superset-frontend/packages/superset-ui-core/test/connection/callApi/parseResponse.test.ts b/superset-frontend/packages/superset-ui-core/test/connection/callApi/parseResponse.test.ts index b08b5b8cb80c4..789910c977be4 100644 --- a/superset-frontend/packages/superset-ui-core/test/connection/callApi/parseResponse.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/connection/callApi/parseResponse.test.ts @@ -27,7 +27,7 @@ describe('parseResponse()', () => { fetchMock.get(LOGIN_GLOB, { result: '1234' }); }); - afterAll(fetchMock.restore); + afterAll(() => fetchMock.restore()); const mockGetUrl = '/mock/get/url'; const mockPostUrl = '/mock/post/url'; @@ -38,12 +38,14 @@ describe('parseResponse()', () => { const mockPostPayload = { post: 'payload' }; const mockErrorPayload = { status: 500, statusText: 'Internal error' }; - fetchMock.get(mockGetUrl, mockGetPayload); - fetchMock.post(mockPostUrl, mockPostPayload); - fetchMock.get(mockErrorUrl, () => Promise.reject(mockErrorPayload)); - fetchMock.get(mockNoParseUrl, new Response('test response')); + beforeEach(() => { + fetchMock.get(mockGetUrl, mockGetPayload); + fetchMock.post(mockPostUrl, mockPostPayload); + fetchMock.get(mockErrorUrl, () => Promise.reject(mockErrorPayload)); + fetchMock.get(mockNoParseUrl, new Response('test response')); + }); - afterEach(fetchMock.reset); + afterEach(() => fetchMock.reset()); it('returns a Promise', () => { const apiPromise = callApi({ url: mockGetUrl, method: 'GET' }); diff --git a/superset-frontend/packages/superset-ui-core/test/query/api/legacy/getDatasourceMetadata.test.ts b/superset-frontend/packages/superset-ui-core/test/query/api/legacy/getDatasourceMetadata.test.ts index 91ba94083d15e..c5bb3fcd83a1f 100644 --- a/superset-frontend/packages/superset-ui-core/test/query/api/legacy/getDatasourceMetadata.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/query/api/legacy/getDatasourceMetadata.test.ts @@ -22,9 +22,9 @@ import { getDatasourceMetadata } from '../../../../src/query/api/legacy'; import setupClientForTest from '../setupClientForTest'; describe('getFormData()', () => { - beforeAll(setupClientForTest); + beforeAll(() => setupClientForTest()); - afterEach(fetchMock.restore); + afterEach(() => fetchMock.restore()); it('returns datasource metadata for given datasource key', () => { const mockData = { diff --git a/superset-frontend/packages/superset-ui-core/test/query/api/legacy/getFormData.test.ts b/superset-frontend/packages/superset-ui-core/test/query/api/legacy/getFormData.test.ts index b5530560e3c3c..8bb3fb2979b0a 100644 --- a/superset-frontend/packages/superset-ui-core/test/query/api/legacy/getFormData.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/query/api/legacy/getFormData.test.ts @@ -22,9 +22,9 @@ import { getFormData } from '../../../../src/query/api/legacy'; import setupClientForTest from '../setupClientForTest'; describe('getFormData()', () => { - beforeAll(setupClientForTest); + beforeAll(() => setupClientForTest()); - afterEach(fetchMock.restore); + afterEach(() => fetchMock.restore()); const mockData = { datasource: '1__table', diff --git a/superset-frontend/packages/superset-ui-core/test/query/api/setupClientForTest.ts b/superset-frontend/packages/superset-ui-core/test/query/api/setupClientForTest.ts index 6df7cd84f591d..bc0c9783937ed 100644 --- a/superset-frontend/packages/superset-ui-core/test/query/api/setupClientForTest.ts +++ b/superset-frontend/packages/superset-ui-core/test/query/api/setupClientForTest.ts @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ +// eslint-disable-next-line import/no-extraneous-dependencies -- The below fetch-mock import shouldn't be considered as direct dependency import fetchMock from 'fetch-mock'; import { SupersetClient } from '@superset-ui/core'; diff --git a/superset-frontend/packages/superset-ui-core/test/query/api/v1/getChartData.test.ts b/superset-frontend/packages/superset-ui-core/test/query/api/v1/getChartData.test.ts index 24d8dcbf91f76..1f6b3ce429951 100644 --- a/superset-frontend/packages/superset-ui-core/test/query/api/v1/getChartData.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/query/api/v1/getChartData.test.ts @@ -21,8 +21,8 @@ import { buildQueryContext, ApiV1 } from '@superset-ui/core'; import setupClientForTest from '../setupClientForTest'; describe('API v1 > getChartData()', () => { - beforeAll(setupClientForTest); - afterEach(fetchMock.restore); + beforeAll(() => setupClientForTest()); + afterEach(() => fetchMock.restore()); it('returns a promise of ChartDataResponse', async () => { const response = { diff --git a/superset-frontend/packages/superset-ui-core/test/query/api/v1/makeApi.test.ts b/superset-frontend/packages/superset-ui-core/test/query/api/v1/makeApi.test.ts index f8cd445250455..286ef35cc03b3 100644 --- a/superset-frontend/packages/superset-ui-core/test/query/api/v1/makeApi.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/query/api/v1/makeApi.test.ts @@ -22,8 +22,8 @@ import { makeApi, SupersetApiError } from '../../../../src/query'; import setupClientForTest from '../setupClientForTest'; describe('makeApi()', () => { - beforeAll(setupClientForTest); - afterEach(fetchMock.restore); + beforeAll(() => setupClientForTest()); + afterEach(() => fetchMock.restore()); it('should expose method and endpoint', () => { const api = makeApi({ diff --git a/superset-frontend/packages/superset-ui-core/test/time-comparison/fetchTimeRange.test.ts b/superset-frontend/packages/superset-ui-core/test/time-comparison/fetchTimeRange.test.ts index df1e2bc7d9b0d..8aedfc371d158 100644 --- a/superset-frontend/packages/superset-ui-core/test/time-comparison/fetchTimeRange.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/time-comparison/fetchTimeRange.test.ts @@ -25,7 +25,7 @@ import { formatTimeRangeComparison, } from '../../src/time-comparison/fetchTimeRange'; -afterEach(fetchMock.restore); +afterEach(() => fetchMock.restore()); test('generates proper time range string', () => { expect( @@ -56,7 +56,7 @@ test('generates a readable time range', () => { }); test('returns a formatted time range from response', async () => { - fetchMock.get("glob:*/api/v1/time_range/?q='Last+day'", { + fetchMock.get('glob:*/api/v1/time_range/?q=%27Last+day%27', { result: [ { since: '2021-04-13T00:00:00', @@ -73,7 +73,7 @@ test('returns a formatted time range from response', async () => { }); test('returns a formatted time range from empty response', async () => { - fetchMock.get("glob:*/api/v1/time_range/?q='Last+day'", { + fetchMock.get('glob:*/api/v1/time_range/?q=%27Last+day%27', { result: [], }); @@ -84,7 +84,7 @@ test('returns a formatted time range from empty response', async () => { }); test('returns a formatted error message from response', async () => { - fetchMock.getOnce("glob:*/api/v1/time_range/?q='Last+day'", { + fetchMock.get('glob:*/api/v1/time_range/?q=%27Last+day%27', { throws: new Response(JSON.stringify({ message: 'Network error' })), }); let timeRange = await fetchTimeRange('Last day'); @@ -92,8 +92,8 @@ test('returns a formatted error message from response', async () => { error: 'Network error', }); - fetchMock.getOnce( - "glob:*/api/v1/time_range/?q='Last+day'", + fetchMock.get( + 'glob:*/api/v1/time_range/?q=%27Last+day%27', { throws: new Error('Internal Server Error'), }, @@ -104,8 +104,8 @@ test('returns a formatted error message from response', async () => { error: 'Internal Server Error', }); - fetchMock.getOnce( - "glob:*/api/v1/time_range/?q='Last+day'", + fetchMock.get( + 'glob:*/api/v1/time_range/?q=%27Last+day%27', { throws: new Response(JSON.stringify({ statusText: 'Network error' }), { statusText: 'Network error', @@ -117,11 +117,11 @@ test('returns a formatted error message from response', async () => { expect(timeRange).toEqual({ error: 'Network error', }); -}); +}, 10000); test('fetchTimeRange with shift', async () => { fetchMock.getOnce( - "glob:*/api/v1/time_range/?q=!((timeRange:'Last+day'),(shift%3A'last%20month'%2CtimeRange%3A'Last%20day'))", + 'glob:*/api/v1/time_range/?q=!((timeRange:%27Last+day%27),(shift%3A%27last%20month%27%2CtimeRange%3A%27Last%20day%27))', { result: [ { diff --git a/superset-frontend/plugins/legacy-plugin-chart-partition/package.json b/superset-frontend/plugins/legacy-plugin-chart-partition/package.json index 0802eb23f6104..bce6238ef05eb 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-partition/package.json +++ b/superset-frontend/plugins/legacy-plugin-chart-partition/package.json @@ -30,7 +30,7 @@ "peerDependencies": { "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", - "@testing-library/jest-dom": "^5.17.0", + "@testing-library/jest-dom": "*", "@testing-library/react": "^12.1.5", "react": "^16.13.1", "react-dom": "^16.13.1" diff --git a/superset-frontend/plugins/plugin-chart-table/package.json b/superset-frontend/plugins/plugin-chart-table/package.json index 9bf34bfa180ff..da9d4e0b8985f 100644 --- a/superset-frontend/plugins/plugin-chart-table/package.json +++ b/superset-frontend/plugins/plugin-chart-table/package.json @@ -40,10 +40,10 @@ "@superset-ui/chart-controls": "*", "@superset-ui/core": "*", "@testing-library/dom": "^8.20.1", - "@testing-library/jest-dom": "^5.11.6", + "@testing-library/jest-dom": "*", "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^5.0.3", - "@testing-library/user-event": "^12.7.0", + "@testing-library/react-hooks": "*", + "@testing-library/user-event": "*", "@types/classnames": "*", "@types/react": "*", "match-sorter": "^6.3.3", diff --git a/superset-frontend/spec/helpers/testing-library.tsx b/superset-frontend/spec/helpers/testing-library.tsx index 625531f926915..fade497a37e00 100644 --- a/superset-frontend/spec/helpers/testing-library.tsx +++ b/superset-frontend/spec/helpers/testing-library.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import { ReactNode, ReactElement } from 'react'; import { render, diff --git a/superset-frontend/src/SqlLab/components/ShareSqlLabQuery/ShareSqlLabQuery.test.tsx b/superset-frontend/src/SqlLab/components/ShareSqlLabQuery/ShareSqlLabQuery.test.tsx index a1251e8bcfa4e..ec77f08242010 100644 --- a/superset-frontend/src/SqlLab/components/ShareSqlLabQuery/ShareSqlLabQuery.test.tsx +++ b/superset-frontend/src/SqlLab/components/ShareSqlLabQuery/ShareSqlLabQuery.test.tsx @@ -24,7 +24,7 @@ import * as uiCore from '@superset-ui/core'; import { Provider } from 'react-redux'; import { supersetTheme, ThemeProvider } from '@superset-ui/core'; import { render, screen, act } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import userEvent from '@testing-library/user-event'; import * as utils from 'src/utils/common'; import ShareSqlLabQuery from 'src/SqlLab/components/ShareSqlLabQuery'; diff --git a/superset-frontend/src/SqlLab/components/SouthPane/SouthPane.test.tsx b/superset-frontend/src/SqlLab/components/SouthPane/SouthPane.test.tsx index 38ffa445c1612..3fc6df96fba4c 100644 --- a/superset-frontend/src/SqlLab/components/SouthPane/SouthPane.test.tsx +++ b/superset-frontend/src/SqlLab/components/SouthPane/SouthPane.test.tsx @@ -18,7 +18,7 @@ */ import { render } from 'spec/helpers/testing-library'; import SouthPane from 'src/SqlLab/components/SouthPane'; -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import { STATUS_OPTIONS } from 'src/SqlLab/constants'; import { initialState, table, defaultQueryEditor } from 'src/SqlLab/fixtures'; import { denormalizeTimestamp } from '@superset-ui/core'; diff --git a/superset-frontend/src/components/AlteredSliceTag/AlteredSliceTag.test.jsx b/superset-frontend/src/components/AlteredSliceTag/AlteredSliceTag.test.jsx index a378201eabbef..a30d09e1b5941 100644 --- a/superset-frontend/src/components/AlteredSliceTag/AlteredSliceTag.test.jsx +++ b/superset-frontend/src/components/AlteredSliceTag/AlteredSliceTag.test.jsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import { render, screen } from 'spec/helpers/testing-library'; import userEvent from '@testing-library/user-event'; import AlteredSliceTag, { diff --git a/superset-frontend/src/components/ErrorMessage/InvalidSQLErrorMessage.test.tsx b/superset-frontend/src/components/ErrorMessage/InvalidSQLErrorMessage.test.tsx index 9a6953902f6ef..38f4355679541 100644 --- a/superset-frontend/src/components/ErrorMessage/InvalidSQLErrorMessage.test.tsx +++ b/superset-frontend/src/components/ErrorMessage/InvalidSQLErrorMessage.test.tsx @@ -18,7 +18,7 @@ */ import { render } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import { ErrorLevel, ErrorSource, diff --git a/superset-frontend/src/components/ErrorMessage/MarshmallowErrorMessage.test.tsx b/superset-frontend/src/components/ErrorMessage/MarshmallowErrorMessage.test.tsx index 969e0c9d0ab74..6b2e9af5e9d47 100644 --- a/superset-frontend/src/components/ErrorMessage/MarshmallowErrorMessage.test.tsx +++ b/superset-frontend/src/components/ErrorMessage/MarshmallowErrorMessage.test.tsx @@ -17,8 +17,8 @@ * under the License. */ +import '@testing-library/jest-dom'; import { render, screen, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; import { ErrorLevel, ErrorTypeEnum, diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx index dbb1c2fc479a1..a56e969f1be68 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx @@ -17,7 +17,7 @@ * under the License. */ import { Preset } from '@superset-ui/core'; -import userEvent, { specialChars } from '@testing-library/user-event'; +import userEvent from '@testing-library/user-event'; import fetchMock from 'fetch-mock'; import chartQueries from 'spec/fixtures/mockChartQueries'; import { dashboardLayout } from 'spec/fixtures/mockDashboardLayout'; @@ -287,7 +287,7 @@ test('validates the column', async () => { test.skip('validates the default value', async () => { defaultRender(noTemporalColumnsState()); expect(await screen.findByText('birth_names')).toBeInTheDocument(); - userEvent.type(screen.getByRole('combobox'), `Column A${specialChars.enter}`); + userEvent.type(screen.getByRole('combobox'), `Column A{Enter}`); userEvent.click(getCheckbox(DEFAULT_VALUE_REGEX)); await waitFor(() => { expect( diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/tests/CurrentCalendarFrame.test.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/tests/CurrentCalendarFrame.test.tsx index 2b1f0754b410f..a3c6de5fc0d61 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/tests/CurrentCalendarFrame.test.tsx +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/tests/CurrentCalendarFrame.test.tsx @@ -17,7 +17,7 @@ * under the License. */ import { render } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; // For advanced DOM assertions +import '@testing-library/jest-dom'; // For advanced DOM assertions import { CurrentCalendarFrame } from '../components/CurrentCalendarFrame'; import { CurrentWeek } from '../types'; diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.test.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.test.tsx index 2657e5429531a..c2ab5fbf9a18a 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.test.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/ColumnSelectPopover.test.tsx @@ -18,7 +18,7 @@ */ import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; diff --git a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/OAuth2ClientField.test.tsx b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/OAuth2ClientField.test.tsx index 1752eb1960727..6e86835facbc4 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/OAuth2ClientField.test.tsx +++ b/superset-frontend/src/features/databases/DatabaseModal/DatabaseConnectionForm/OAuth2ClientField.test.tsx @@ -18,7 +18,7 @@ */ import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import { ThemeProvider, supersetTheme } from '@superset-ui/core'; import { DatabaseObject } from 'src/features/databases/types'; import { OAuth2ClientField } from './OAuth2ClientField'; diff --git a/superset-frontend/src/features/databases/DatabaseModal/index.test.tsx b/superset-frontend/src/features/databases/DatabaseModal/index.test.tsx index 49b80fc96112e..2f8eafeb7b0cb 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/index.test.tsx +++ b/superset-frontend/src/features/databases/DatabaseModal/index.test.tsx @@ -1409,6 +1409,8 @@ describe('DatabaseModal', () => { const importDbButton = screen.getByTestId( 'import-database-btn', ) as HTMLInputElement; + importDbButton.type = 'file'; + importDbButton.files = {} as FileList; expect(importDbButton).toBeVisible(); const testFile = new File([new ArrayBuffer(1)], 'model_export.zip'); diff --git a/superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx b/superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx index 8a6f4fe92fb31..39ce9506af2e9 100644 --- a/superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx +++ b/superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx @@ -616,7 +616,7 @@ test('CSV, form post', async () => { const inputElement = document.querySelector('input[type="file"]'); if (inputElement) { - userEvent.upload(inputElement, file); + userEvent.upload(inputElement as HTMLElement, file); } const selectDatabase = screen.getByRole('combobox', { @@ -673,7 +673,7 @@ test('Excel, form post', async () => { const inputElement = document.querySelector('input[type="file"]'); if (inputElement) { - userEvent.upload(inputElement, file); + userEvent.upload(inputElement as HTMLElement, file); } const selectDatabase = screen.getByRole('combobox', { @@ -734,7 +734,7 @@ test('Columnar, form post', async () => { const inputElement = document.querySelector('input[type="file"]'); if (inputElement) { - userEvent.upload(inputElement, file); + userEvent.upload(inputElement as HTMLElement, file); } const selectDatabase = screen.getByRole('combobox', { From 47c1e09c755b0dd93d46a3a203ee6bf644c66ea1 Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Fri, 11 Oct 2024 15:45:40 -0400 Subject: [PATCH 11/23] fix: `sqlparse` fallback for formatting queries (#30578) --- superset/sql/parse.py | 108 ++++++++++++++---- tests/integration_tests/sql_lab/api_tests.py | 2 +- tests/unit_tests/db_engine_specs/test_base.py | 16 +-- tests/unit_tests/sql/parse_tests.py | 34 ++++++ 4 files changed, 125 insertions(+), 35 deletions(-) diff --git a/superset/sql/parse.py b/superset/sql/parse.py index 377411b944814..33ed76473facc 100644 --- a/superset/sql/parse.py +++ b/superset/sql/parse.py @@ -26,6 +26,8 @@ from typing import Any, Generic, TypeVar import sqlglot +import sqlparse +from deprecation import deprecated from sqlglot import exp from sqlglot.dialects.dialect import Dialect, Dialects from sqlglot.errors import ParseError @@ -138,9 +140,9 @@ class BaseSQLStatement(Generic[InternalRepresentation]): """ Base class for SQL statements. - The class can be instantiated with a string representation of the script or, for - efficiency reasons, with a pre-parsed AST. This is useful with `sqlglot.parse`, - which will split a script in multiple already parsed statements. + The class should be instantiated with a string representation of the script and, for + efficiency reasons, optionally with a pre-parsed AST. This is useful with + `sqlglot.parse`, which will split a script in multiple already parsed statements. The `engine` parameters comes from the `engine` attribute in a Superset DB engine spec. @@ -148,14 +150,12 @@ class BaseSQLStatement(Generic[InternalRepresentation]): def __init__( self, - statement: str | InternalRepresentation, + statement: str, engine: str, + ast: InternalRepresentation | None = None, ): - self._parsed: InternalRepresentation = ( - self._parse_statement(statement, engine) - if isinstance(statement, str) - else statement - ) + self._sql = statement + self._parsed = ast or self._parse_statement(statement, engine) self.engine = engine self.tables = self._extract_tables_from_statement(self._parsed, self.engine) @@ -239,11 +239,12 @@ class SQLStatement(BaseSQLStatement[exp.Expression]): def __init__( self, - statement: str | exp.Expression, + statement: str, engine: str, + ast: exp.Expression | None = None, ): self._dialect = SQLGLOT_DIALECTS.get(engine) - super().__init__(statement, engine) + super().__init__(statement, engine, ast) @classmethod def _parse(cls, script: str, engine: str) -> list[exp.Expression]: @@ -275,11 +276,47 @@ def split_script( script: str, engine: str, ) -> list[SQLStatement]: - return [ - cls(statement, engine) - for statement in cls._parse(script, engine) - if statement - ] + if engine in SQLGLOT_DIALECTS: + try: + return [ + cls(ast.sql(), engine, ast) + for ast in cls._parse(script, engine) + if ast + ] + except ValueError: + # `ast.sql()` might raise an error on some cases (eg, `SHOW TABLES + # FROM`). In this case, we rely on the tokenizer to generate the + # statements. + pass + + # When we don't have a sqlglot dialect we can't rely on `ast.sql()` to correctly + # generate the SQL of each statement, so we tokenize the script and split it + # based on the location of semi-colons. + statements = [] + start = 0 + remainder = script + + try: + tokens = sqlglot.tokenize(script) + except sqlglot.errors.TokenError as ex: + raise SupersetParseError( + script, + engine, + message="Unable to tokenize script", + ) from ex + + for token in tokens: + if token.token_type == sqlglot.TokenType.SEMICOLON: + statement, start = script[start : token.start], token.end + 1 + ast = cls._parse(statement, engine)[0] + statements.append(cls(statement.strip(), engine, ast)) + remainder = script[start:] + + if remainder.strip(): + ast = cls._parse(remainder, engine)[0] + statements.append(cls(remainder.strip(), engine, ast)) + + return statements @classmethod def _parse_statement( @@ -349,8 +386,34 @@ def format(self, comments: bool = True) -> str: """ Pretty-format the SQL statement. """ - write = Dialect.get_or_raise(self._dialect) - return write.generate(self._parsed, copy=False, comments=comments, pretty=True) + if self._dialect: + try: + write = Dialect.get_or_raise(self._dialect) + return write.generate( + self._parsed, + copy=False, + comments=comments, + pretty=True, + ) + except ValueError: + pass + + return self._fallback_formatting() + + @deprecated(deprecated_in="4.0", removed_in="5.0") + def _fallback_formatting(self) -> str: + """ + Format SQL without a specific dialect. + + Reformatting SQL using the generic sqlglot dialect is known to break queries. + For example, it will change `foo NOT IN (1, 2)` to `NOT foo IN (1,2)`, which + breaks the query for Firebolt. To avoid this, we use sqlparse for formatting + when the dialect is not known. + + In 5.0 we should remove `sqlparse`, and the method should return the query + unmodified. + """ + return sqlparse.format(self._sql, reindent=True, keyword_case="upper") def get_settings(self) -> dict[str, str | bool]: """ @@ -456,7 +519,9 @@ def split_script( https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/scalar-data-types/string for more information. """ - return [cls(statement, engine) for statement in split_kql(script)] + return [ + cls(statement, engine, statement.strip()) for statement in split_kql(script) + ] @classmethod def _parse_statement( @@ -498,7 +563,7 @@ def format(self, comments: bool = True) -> str: """ Pretty-format the SQL statement. """ - return self._parsed + return self._sql.strip() def get_settings(self) -> dict[str, str | bool]: """ @@ -548,6 +613,9 @@ def __init__( def format(self, comments: bool = True) -> str: """ Pretty-format the SQL script. + + Note that even though KQL is very different from SQL, multiple statements are + still separated by semi-colons. """ return ";\n".join(statement.format(comments) for statement in self.statements) diff --git a/tests/integration_tests/sql_lab/api_tests.py b/tests/integration_tests/sql_lab/api_tests.py index 19d6e56fb6441..cf1e190bbb9ba 100644 --- a/tests/integration_tests/sql_lab/api_tests.py +++ b/tests/integration_tests/sql_lab/api_tests.py @@ -281,7 +281,7 @@ def test_format_sql_request(self): "/api/v1/sqllab/format_sql/", json=data, ) - success_resp = {"result": "SELECT\n 1\nFROM my_table"} + success_resp = {"result": "SELECT 1\nFROM my_table"} resp_data = json.loads(rv.data.decode("utf-8")) self.assertDictEqual(resp_data, success_resp) # noqa: PT009 assert rv.status_code == 200 diff --git a/tests/unit_tests/db_engine_specs/test_base.py b/tests/unit_tests/db_engine_specs/test_base.py index a3af155815d1c..d8e632ce09336 100644 --- a/tests/unit_tests/db_engine_specs/test_base.py +++ b/tests/unit_tests/db_engine_specs/test_base.py @@ -241,14 +241,7 @@ class NoLimitDBEngineSpec(BaseEngineSpec): latest_partition=False, cols=cols, ) - assert ( - sql - == """SELECT - a -FROM my_table -LIMIT ? -OFFSET ?""" - ) + assert sql == "SELECT a\nFROM my_table\nLIMIT ?\nOFFSET ?" sql = NoLimitDBEngineSpec.select_star( database=database, @@ -260,12 +253,7 @@ class NoLimitDBEngineSpec(BaseEngineSpec): latest_partition=False, cols=cols, ) - assert ( - sql - == """SELECT - a -FROM my_table""" - ) + assert sql == "SELECT a\nFROM my_table" def test_extra_table_metadata(mocker: MockerFixture) -> None: diff --git a/tests/unit_tests/sql/parse_tests.py b/tests/unit_tests/sql/parse_tests.py index ae5ebf89a8b96..ada6314457fbc 100644 --- a/tests/unit_tests/sql/parse_tests.py +++ b/tests/unit_tests/sql/parse_tests.py @@ -284,6 +284,40 @@ def test_extract_tables_show_tables_from() -> None: ) +def test_format_show_tables() -> None: + """ + Test format when `ast.sql()` raises an exception. + + In that case sqlparse should be used instead. + """ + assert ( + SQLScript("SHOW TABLES FROM s1 like '%order%'", "mysql").format() + == "SHOW TABLES FROM s1 LIKE '%order%'" + ) + + +def test_format_no_dialect() -> None: + """ + Test format with an engine that has no corresponding dialect. + """ + assert ( + SQLScript("SELECT col FROM t WHERE col NOT IN (1, 2)", "firebolt").format() + == "SELECT col\nFROM t\nWHERE col NOT IN (1,\n 2)" + ) + + +def test_split_no_dialect() -> None: + """ + Test the statement split when the engine has no corresponding dialect. + """ + sql = "SELECT col FROM t WHERE col NOT IN (1, 2); SELECT * FROM t; SELECT foo" + statements = SQLScript(sql, "firebolt").statements + assert len(statements) == 3 + assert statements[0]._sql == "SELECT col FROM t WHERE col NOT IN (1, 2)" + assert statements[1]._sql == "SELECT * FROM t" + assert statements[2]._sql == "SELECT foo" + + def test_extract_tables_show_columns_from() -> None: """ Test `SHOW COLUMNS FROM`. From 0e9c0f621ac9ddbcf889045f3d4772b1ee213e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kope=C4=87?= <3338226+mkopec87@users.noreply.github.com> Date: Sat, 12 Oct 2024 01:02:03 +0200 Subject: [PATCH 12/23] feat(formatting): Add memory units adaptive formatter to format bytes (#30559) --- .../src/utils/D3Formatting.ts | 2 + .../factories/createMemoryFormatter.ts | 55 +++++++++++ .../src/number-format/index.ts | 1 + .../factories/createMemoryFormatter.test.ts | 94 +++++++++++++++++++ .../test/number-format/index.test.ts | 2 + .../src/setup/setupFormatters.ts | 5 +- 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 superset-frontend/packages/superset-ui-core/src/number-format/factories/createMemoryFormatter.ts create mode 100644 superset-frontend/packages/superset-ui-core/test/number-format/factories/createMemoryFormatter.test.ts diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/utils/D3Formatting.ts b/superset-frontend/packages/superset-ui-chart-controls/src/utils/D3Formatting.ts index a8fd6312cbd1f..5541c4a4b4574 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/D3Formatting.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/D3Formatting.ts @@ -57,6 +57,8 @@ export const D3_FORMAT_OPTIONS: [string, string][] = [ ...d3Formatted, ['DURATION', t('Duration in ms (66000 => 1m 6s)')], ['DURATION_SUB', t('Duration in ms (1.40008 => 1ms 400µs 80ns)')], + ['MEMORY_DECIMAL', t('Memory in bytes - decimal (1024B => 1.024kB)')], + ['MEMORY_BINARY', t('Memory in bytes - binary (1024B => 1KiB)')], ]; export const D3_TIME_FORMAT_DOCS = t( diff --git a/superset-frontend/packages/superset-ui-core/src/number-format/factories/createMemoryFormatter.ts b/superset-frontend/packages/superset-ui-core/src/number-format/factories/createMemoryFormatter.ts new file mode 100644 index 0000000000000..8d62948939a67 --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/number-format/factories/createMemoryFormatter.ts @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import NumberFormatter from '../NumberFormatter'; + +export default function createMemoryFormatter( + config: { + description?: string; + id?: string; + label?: string; + binary?: boolean; + decimals?: number; + } = {}, +) { + const { description, id, label, binary, decimals = 2 } = config; + + return new NumberFormatter({ + description, + formatFunc: value => { + if (value === 0) return '0B'; + + const sign = value > 0 ? '' : '-'; + const absValue = Math.abs(value); + + const suffixes = binary + ? ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] + : ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'RB', 'QB']; + const base = binary ? 1024 : 1000; + + const i = Math.min( + suffixes.length - 1, + Math.floor(Math.log(absValue) / Math.log(base)), + ); + return `${sign}${parseFloat((absValue / Math.pow(base, i)).toFixed(decimals))}${suffixes[i]}`; + }, + id: id ?? 'memory_format', + label: label ?? `Memory formatter`, + }); +} diff --git a/superset-frontend/packages/superset-ui-core/src/number-format/index.ts b/superset-frontend/packages/superset-ui-core/src/number-format/index.ts index c65537552ee41..b9835d332d0e0 100644 --- a/superset-frontend/packages/superset-ui-core/src/number-format/index.ts +++ b/superset-frontend/packages/superset-ui-core/src/number-format/index.ts @@ -31,5 +31,6 @@ export { export { default as NumberFormatterRegistry } from './NumberFormatterRegistry'; export { default as createD3NumberFormatter } from './factories/createD3NumberFormatter'; export { default as createDurationFormatter } from './factories/createDurationFormatter'; +export { default as createMemoryFormatter } from './factories/createMemoryFormatter'; export { default as createSiAtMostNDigitFormatter } from './factories/createSiAtMostNDigitFormatter'; export { default as createSmartNumberFormatter } from './factories/createSmartNumberFormatter'; diff --git a/superset-frontend/packages/superset-ui-core/test/number-format/factories/createMemoryFormatter.test.ts b/superset-frontend/packages/superset-ui-core/test/number-format/factories/createMemoryFormatter.test.ts new file mode 100644 index 0000000000000..e4dc37d77afb5 --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/test/number-format/factories/createMemoryFormatter.test.ts @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { NumberFormatter, createMemoryFormatter } from '@superset-ui/core'; + +test('creates an instance of MemoryFormatter', () => { + const formatter = createMemoryFormatter(); + expect(formatter).toBeInstanceOf(NumberFormatter); +}); + +test('formats bytes in human readable format with default options', () => { + const formatter = createMemoryFormatter(); + expect(formatter(0)).toBe('0B'); + expect(formatter(50)).toBe('50B'); + expect(formatter(555)).toBe('555B'); + expect(formatter(1000)).toBe('1kB'); + expect(formatter(1111)).toBe('1.11kB'); + expect(formatter(1024)).toBe('1.02kB'); + expect(formatter(1337)).toBe('1.34kB'); + expect(formatter(1999)).toBe('2kB'); + expect(formatter(10 * 1000)).toBe('10kB'); + expect(formatter(100 * 1000)).toBe('100kB'); + expect(formatter(Math.pow(1000, 2))).toBe('1MB'); + expect(formatter(Math.pow(1000, 3))).toBe('1GB'); + expect(formatter(Math.pow(1000, 4))).toBe('1TB'); + expect(formatter(Math.pow(1000, 5))).toBe('1PB'); + expect(formatter(Math.pow(1000, 6))).toBe('1EB'); + expect(formatter(Math.pow(1000, 7))).toBe('1ZB'); + expect(formatter(Math.pow(1000, 8))).toBe('1YB'); + expect(formatter(Math.pow(1000, 9))).toBe('1RB'); + expect(formatter(Math.pow(1000, 10))).toBe('1QB'); + expect(formatter(Math.pow(1000, 11))).toBe('1000QB'); + expect(formatter(Math.pow(1000, 12))).toBe('1000000QB'); +}); + +test('formats negative bytes in human readable format with default options', () => { + const formatter = createMemoryFormatter(); + expect(formatter(-50)).toBe('-50B'); +}); + +test('formats float bytes in human readable format with default options', () => { + const formatter = createMemoryFormatter(); + expect(formatter(10.666)).toBe('10.67B'); + expect(formatter(1200.666)).toBe('1.2kB'); +}); + +test('formats bytes in human readable format with additional binary option', () => { + const formatter = createMemoryFormatter({ binary: true }); + expect(formatter(0)).toBe('0B'); + expect(formatter(50)).toBe('50B'); + expect(formatter(555)).toBe('555B'); + expect(formatter(1000)).toBe('1000B'); + expect(formatter(1111)).toBe('1.08KiB'); + expect(formatter(1024)).toBe('1KiB'); + expect(formatter(1337)).toBe('1.31KiB'); + expect(formatter(2047)).toBe('2KiB'); + expect(formatter(10 * 1024)).toBe('10KiB'); + expect(formatter(100 * 1024)).toBe('100KiB'); + expect(formatter(Math.pow(1024, 2))).toBe('1MiB'); + expect(formatter(Math.pow(1024, 3))).toBe('1GiB'); + expect(formatter(Math.pow(1024, 4))).toBe('1TiB'); + expect(formatter(Math.pow(1024, 5))).toBe('1PiB'); + expect(formatter(Math.pow(1024, 6))).toBe('1EiB'); + expect(formatter(Math.pow(1024, 7))).toBe('1ZiB'); + expect(formatter(Math.pow(1024, 8))).toBe('1YiB'); + expect(formatter(Math.pow(1024, 9))).toBe('1024YiB'); + expect(formatter(Math.pow(1024, 10))).toBe('1048576YiB'); +}); + +test('formats bytes in human readable format with additional decimals option', () => { + const formatter0decimals = createMemoryFormatter({ decimals: 0 }); + expect(formatter0decimals(0)).toBe('0B'); + expect(formatter0decimals(1111)).toBe('1kB'); + + const formatter3decimals = createMemoryFormatter({ decimals: 3 }); + expect(formatter3decimals(0)).toBe('0B'); + expect(formatter3decimals(1111)).toBe('1.111kB'); +}); diff --git a/superset-frontend/packages/superset-ui-core/test/number-format/index.test.ts b/superset-frontend/packages/superset-ui-core/test/number-format/index.test.ts index 09395e722e6e2..103f5e44a9b7d 100644 --- a/superset-frontend/packages/superset-ui-core/test/number-format/index.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/number-format/index.test.ts @@ -21,6 +21,7 @@ import { createD3NumberFormatter, createDurationFormatter, createSiAtMostNDigitFormatter, + createMemoryFormatter, formatNumber, getNumberFormatter, getNumberFormatterRegistry, @@ -35,6 +36,7 @@ describe('index', () => { createD3NumberFormatter, createDurationFormatter, createSiAtMostNDigitFormatter, + createMemoryFormatter, formatNumber, getNumberFormatter, getNumberFormatterRegistry, diff --git a/superset-frontend/src/setup/setupFormatters.ts b/superset-frontend/src/setup/setupFormatters.ts index e18aeba9dcb3e..384b1be9e30ae 100644 --- a/superset-frontend/src/setup/setupFormatters.ts +++ b/superset-frontend/src/setup/setupFormatters.ts @@ -28,6 +28,7 @@ import { createSmartDateFormatter, createSmartDateVerboseFormatter, createSmartDateDetailedFormatter, + createMemoryFormatter, } from '@superset-ui/core'; import { FormatLocaleDefinition } from 'd3-format'; import { TimeLocaleDefinition } from 'd3-time-format'; @@ -76,7 +77,9 @@ export default function setupFormatters( .registerValue( 'DURATION_SUB', createDurationFormatter({ formatSubMilliseconds: true }), - ); + ) + .registerValue('MEMORY_DECIMAL', createMemoryFormatter({ binary: false })) + .registerValue('MEMORY_BINARY', createMemoryFormatter({ binary: true })); const timeFormatterRegistry = getTimeFormatterRegistry(); From 6ede3271ff3e4c82a53a08e0dd18b35e01c4fa4d Mon Sep 17 00:00:00 2001 From: anamitraadhikari <97945303+anamitraadhikari@users.noreply.github.com> Date: Mon, 14 Oct 2024 18:03:28 -0700 Subject: [PATCH 13/23] fix(SQL Lab): hang when result set size is too big (#30522) Co-authored-by: aadhikari Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com> --- docs/static/resources/openapi.json | 3 +- .../superset-ui-core/src/query/types/Query.ts | 1 + .../src/setup/setupErrorMessages.ts | 4 + superset/config.py | 3 + superset/errors.py | 3 + superset/sql_lab.py | 36 ++++++ tests/unit_tests/sql_lab_test.py | 115 +++++++++++++++++- 7 files changed, 162 insertions(+), 3 deletions(-) diff --git a/docs/static/resources/openapi.json b/docs/static/resources/openapi.json index a039bd3a2a51f..43781ac9658b1 100644 --- a/docs/static/resources/openapi.json +++ b/docs/static/resources/openapi.json @@ -116,7 +116,8 @@ "GENERIC_BACKEND_ERROR", "INVALID_PAYLOAD_FORMAT_ERROR", "INVALID_PAYLOAD_SCHEMA_ERROR", - "REPORT_NOTIFICATION_ERROR" + "REPORT_NOTIFICATION_ERROR", + "RESULT_TOO_LARGE_ERROR" ], "type": "string" }, diff --git a/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts b/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts index 4feba17319e55..a83d17a937f6a 100644 --- a/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts +++ b/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts @@ -227,6 +227,7 @@ export const ErrorTypeEnum = { ASYNC_WORKERS_ERROR: 'ASYNC_WORKERS_ERROR', ADHOC_SUBQUERY_NOT_ALLOWED_ERROR: 'ADHOC_SUBQUERY_NOT_ALLOWED_ERROR', INVALID_SQL_ERROR: 'INVALID_SQL_ERROR', + RESULT_TOO_LARGE_ERROR: 'RESULT_TOO_LARGE_ERROR', // Generic errors GENERIC_COMMAND_ERROR: 'GENERIC_COMMAND_ERROR', diff --git a/superset-frontend/src/setup/setupErrorMessages.ts b/superset-frontend/src/setup/setupErrorMessages.ts index 442cd32152bc9..e4c2380150c9d 100644 --- a/superset-frontend/src/setup/setupErrorMessages.ts +++ b/superset-frontend/src/setup/setupErrorMessages.ts @@ -159,5 +159,9 @@ export default function setupErrorMessages() { ErrorTypeEnum.INVALID_SQL_ERROR, InvalidSQLErrorMessage, ); + errorMessageComponentRegistry.registerValue( + ErrorTypeEnum.RESULT_TOO_LARGE_ERROR, + DatabaseErrorMessage, + ); setupErrorMessagesExtra(); } diff --git a/superset/config.py b/superset/config.py index 7ae46bba76f36..d19e30a5a5282 100644 --- a/superset/config.py +++ b/superset/config.py @@ -960,6 +960,9 @@ class D3TimeFormat(TypedDict, total=False): SQLLAB_SAVE_WARNING_MESSAGE = None SQLLAB_SCHEDULE_WARNING_MESSAGE = None +# Max payload size (MB) for SQL Lab to prevent browser hangs with large results. +SQLLAB_PAYLOAD_MAX_MB = None + # Force refresh while auto-refresh in dashboard DASHBOARD_AUTO_REFRESH_MODE: Literal["fetch", "force"] = "force" # Dashboard auto refresh intervals diff --git a/superset/errors.py b/superset/errors.py index 9f0f5bed05354..4d9c08d14214d 100644 --- a/superset/errors.py +++ b/superset/errors.py @@ -87,6 +87,7 @@ class SupersetErrorType(StrEnum): ASYNC_WORKERS_ERROR = "ASYNC_WORKERS_ERROR" ADHOC_SUBQUERY_NOT_ALLOWED_ERROR = "ADHOC_SUBQUERY_NOT_ALLOWED_ERROR" INVALID_SQL_ERROR = "INVALID_SQL_ERROR" + RESULT_TOO_LARGE_ERROR = "RESULT_TOO_LARGE_ERROR" # Generic errors GENERIC_COMMAND_ERROR = "GENERIC_COMMAND_ERROR" @@ -151,6 +152,7 @@ class SupersetErrorType(StrEnum): 1036: _("The database was deleted."), 1037: _("Custom SQL fields cannot contain sub-queries."), 1040: _("The submitted payload failed validation."), + 1041: _("The result size exceeds the allowed limit."), } @@ -190,6 +192,7 @@ class SupersetErrorType(StrEnum): SupersetErrorType.DATABASE_NOT_FOUND_ERROR: [1011, 1036], SupersetErrorType.CONNECTION_DATABASE_TIMEOUT: [1001, 1009], SupersetErrorType.MARSHMALLOW_ERROR: [1040], + SupersetErrorType.RESULT_TOO_LARGE_ERROR: [1041], } diff --git a/superset/sql_lab.py b/superset/sql_lab.py index 7685b4419ce37..88e1bc1aad858 100644 --- a/superset/sql_lab.py +++ b/superset/sql_lab.py @@ -17,6 +17,7 @@ # pylint: disable=consider-using-transaction import dataclasses import logging +import sys import uuid from contextlib import closing from datetime import datetime @@ -78,6 +79,7 @@ SQLLAB_CTAS_NO_LIMIT = config["SQLLAB_CTAS_NO_LIMIT"] log_query = config["QUERY_LOGGER"] logger = logging.getLogger(__name__) +BYTES_IN_MB = 1024 * 1024 class SqlLabException(Exception): @@ -531,6 +533,7 @@ def execute_sql_statements( log_params, apply_ctas, ) + except SqlLabQueryStoppedException: payload.update({"status": QueryStatus.STOPPED}) return payload @@ -601,6 +604,22 @@ def execute_sql_statements( serialized_payload = _serialize_payload( payload, cast(bool, results_backend_use_msgpack) ) + + # Check the size of the serialized payload + if sql_lab_payload_max_mb := config.get("SQLLAB_PAYLOAD_MAX_MB"): + serialized_payload_size = sys.getsizeof(serialized_payload) + max_bytes = sql_lab_payload_max_mb * BYTES_IN_MB + + if serialized_payload_size > max_bytes: + logger.info("Result size exceeds the allowed limit.") + raise SupersetErrorException( + SupersetError( + message=f"Result size ({serialized_payload_size / BYTES_IN_MB:.2f} MB) exceeds the allowed limit of {sql_lab_payload_max_mb} MB.", + error_type=SupersetErrorType.RESULT_TOO_LARGE_ERROR, + level=ErrorLevel.ERROR, + ) + ) + cache_timeout = database.cache_timeout if cache_timeout is None: cache_timeout = config["CACHE_DEFAULT_TIMEOUT"] @@ -635,6 +654,23 @@ def execute_sql_statements( "expanded_columns": expanded_columns, } ) + # Check the size of the serialized payload (opt-in logic for return_results) + if sql_lab_payload_max_mb := config.get("SQLLAB_PAYLOAD_MAX_MB"): + serialized_payload = _serialize_payload( + payload, cast(bool, results_backend_use_msgpack) + ) + serialized_payload_size = sys.getsizeof(serialized_payload) + max_bytes = sql_lab_payload_max_mb * BYTES_IN_MB + + if serialized_payload_size > max_bytes: + logger.info("Result size exceeds the allowed limit.") + raise SupersetErrorException( + SupersetError( + message=f"Result size ({serialized_payload_size / BYTES_IN_MB:.2f} MB) exceeds the allowed limit of {sql_lab_payload_max_mb} MB.", + error_type=SupersetErrorType.RESULT_TOO_LARGE_ERROR, + level=ErrorLevel.ERROR, + ) + ) return payload return None diff --git a/tests/unit_tests/sql_lab_test.py b/tests/unit_tests/sql_lab_test.py index 83093352bca8f..cc9b146f39be5 100644 --- a/tests/unit_tests/sql_lab_test.py +++ b/tests/unit_tests/sql_lab_test.py @@ -17,8 +17,10 @@ # pylint: disable=import-outside-toplevel, invalid-name, unused-argument, too-many-locals import json +from unittest import mock from uuid import UUID +import pytest import sqlparse from freezegun import freeze_time from pytest_mock import MockerFixture @@ -27,9 +29,9 @@ from superset import db from superset.common.db_query_status import QueryStatus from superset.errors import ErrorLevel, SupersetErrorType -from superset.exceptions import OAuth2Error +from superset.exceptions import OAuth2Error, SupersetErrorException from superset.models.core import Database -from superset.sql_lab import get_sql_results +from superset.sql_lab import execute_sql_statements, get_sql_results from superset.utils.core import override_user from tests.unit_tests.models.core_test import oauth2_client_info @@ -125,6 +127,115 @@ def test_execute_sql_statement_with_rls( SupersetResultSet.assert_called_with([(42,)], cursor.description, db_engine_spec) +@mock.patch.dict( + "superset.sql_lab.config", + {"SQLLAB_PAYLOAD_MAX_MB": 50}, # Set the desired config value for testing +) +def test_execute_sql_statement_exceeds_payload_limit(mocker: MockerFixture) -> None: + """ + Test for `execute_sql_statements` when the result payload size exceeds the limit. + """ + + # Mock the query object and database + query = mocker.MagicMock() + query.limit = 1 + query.database = mocker.MagicMock() + query.database.db_engine_spec.is_select_query.return_value = True + query.database.cache_timeout = 100 + query.status = "RUNNING" + query.select_as_cta = False + query.database.allow_run_async = True + + # Mock get_query to return our mocked query object + mocker.patch("superset.sql_lab.get_query", return_value=query) + + # Mock sys.getsizeof to simulate a large payload size + mocker.patch("sys.getsizeof", return_value=100000000) # 100 MB + + # Mock _serialize_payload + def mock_serialize_payload(payload, use_msgpack): + return "serialized_payload" + + mocker.patch( + "superset.sql_lab._serialize_payload", side_effect=mock_serialize_payload + ) + + # Mock db.session.refresh to avoid AttributeError during session refresh + mocker.patch("superset.sql_lab.db.session.refresh", return_value=None) + + # Mock the results backend to avoid "Results backend is not configured" error + mocker.patch("superset.sql_lab.results_backend", return_value=True) + + # Test that the exception is raised when the payload exceeds the limit + with pytest.raises(SupersetErrorException): + execute_sql_statements( + query_id=1, + rendered_query="SELECT 42 AS answer", + return_results=True, # Simulate that results are being returned + store_results=True, # Not storing results but returning them + start_time=None, + expand_data=False, + log_params={}, + ) + + +@mock.patch.dict( + "superset.sql_lab.config", + {"SQLLAB_PAYLOAD_MAX_MB": 50}, # Set the desired config value for testing +) +def test_execute_sql_statement_within_payload_limit(mocker: MockerFixture) -> None: + """ + Test for `execute_sql_statements` when the result payload size is within the limit, + and check if the flow executes smoothly without raising any exceptions. + """ + + # Mock the query object and database + query = mocker.MagicMock() + query.limit = 1 + query.database = mocker.MagicMock() + query.database.db_engine_spec.is_select_query.return_value = True + query.database.cache_timeout = 100 + query.status = "RUNNING" + query.select_as_cta = False + query.database.allow_run_async = True + + # Mock get_query to return our mocked query object + mocker.patch("superset.sql_lab.get_query", return_value=query) + + # Mock sys.getsizeof to simulate a payload size that is within the limit + mocker.patch("sys.getsizeof", return_value=10000000) # 10 MB (within limit) + + # Mock _serialize_payload + def mock_serialize_payload(payload, use_msgpack): + return "serialized_payload" + + mocker.patch( + "superset.sql_lab._serialize_payload", side_effect=mock_serialize_payload + ) + + # Mock db.session.refresh to avoid AttributeError during session refresh + mocker.patch("superset.sql_lab.db.session.refresh", return_value=None) + + # Mock the results backend to avoid "Results backend is not configured" error + mocker.patch("superset.sql_lab.results_backend", return_value=True) + + # Test that no exception is raised and the function executes smoothly + try: + execute_sql_statements( + query_id=1, + rendered_query="SELECT 42 AS answer", + return_results=True, # Simulate that results are being returned + store_results=True, # Not storing results but returning them + start_time=None, + expand_data=False, + log_params={}, + ) + except SupersetErrorException: + pytest.fail( + "SupersetErrorException should not have been raised for payload within the limit" + ) + + def test_sql_lab_insert_rls_as_subquery( mocker: MockerFixture, session: Session, From 2c3ba95768e27e85575e6db57c53620997a662e4 Mon Sep 17 00:00:00 2001 From: ObservabilityTeam <162349725+ObservabilityTeam@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:44:31 +0200 Subject: [PATCH 14/23] fix(filters): Adds a fix for saving time range adhoc_filters (#30581) Co-authored-by: Muhammad Musfir --- .../explore/actions/saveModalActions.test.ts | 60 ++++++++++++++++++- .../src/explore/actions/saveModalActions.ts | 29 +++++---- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/superset-frontend/src/explore/actions/saveModalActions.test.ts b/superset-frontend/src/explore/actions/saveModalActions.test.ts index 062379e5d3224..0368693f856dd 100644 --- a/superset-frontend/src/explore/actions/saveModalActions.test.ts +++ b/superset-frontend/src/explore/actions/saveModalActions.test.ts @@ -20,7 +20,11 @@ import sinon from 'sinon'; import fetchMock from 'fetch-mock'; import { Dispatch } from 'redux'; import { ADD_TOAST } from 'src/components/MessageToasts/actions'; -import { DatasourceType, QueryFormData } from '@superset-ui/core'; +import { + DatasourceType, + QueryFormData, + SimpleAdhocFilter, +} from '@superset-ui/core'; import { createDashboard, createSlice, @@ -31,6 +35,7 @@ import { getSlicePayload, PayloadSlice, } from './saveModalActions'; +import { Operators } from '../constants'; // Define test constants and mock data using imported types const sliceId = 10; @@ -594,6 +599,7 @@ describe('getSlicePayload', () => { }, ], }; + const formDataWithAdhocFiltersWithExtra: QueryFormData = { ...formDataWithNativeFilters, viz_type: 'mixed_timeseries', @@ -625,11 +631,61 @@ describe('getSlicePayload', () => { owners as [], formDataFromSliceWithAdhocFilterB, ); + expect(JSON.parse(result.params as string).adhoc_filters).toEqual( formDataFromSliceWithAdhocFilterB.adhoc_filters, ); - expect(JSON.parse(result.params as string).adhoc_filters).toEqual( + expect(JSON.parse(result.params as string).adhoc_filters_b).toEqual( formDataFromSliceWithAdhocFilterB.adhoc_filters_b, ); }); + + test('should return the correct payload when formDataFromSliceWithAdhocFilter has no time range filters in mixed chart', () => { + const formDataFromSliceWithAdhocFilterB: QueryFormData = { + ...formDataFromSlice, + adhoc_filters: [], + adhoc_filters_b: [], + }; + + const formDataWithAdhocFiltersWithExtra: QueryFormData = { + ...formDataWithNativeFilters, + viz_type: 'mixed_timeseries', + adhoc_filters: [ + { + clause: 'WHERE', + subject: 'year', + operator: 'TEMPORAL_RANGE', + comparator: 'No filter', + expressionType: 'SIMPLE', + isExtra: true, + }, + ], + adhoc_filters_b: [ + { + clause: 'WHERE', + subject: 'year', + operator: 'TEMPORAL_RANGE', + comparator: 'No filter', + expressionType: 'SIMPLE', + isExtra: true, + }, + ], + }; + const result = getSlicePayload( + sliceName, + formDataWithAdhocFiltersWithExtra, + dashboards, + owners as [], + formDataFromSliceWithAdhocFilterB, + ); + + const hasTemporalRange = ( + JSON.parse(result.params as string).adhoc_filters_b || [] + ).some( + (filter: SimpleAdhocFilter) => + filter.operator === Operators.TemporalRange, + ); + + expect(hasTemporalRange).toBe(true); + }); }); diff --git a/superset-frontend/src/explore/actions/saveModalActions.ts b/superset-frontend/src/explore/actions/saveModalActions.ts index a66dba3a7b681..42f2c0686c85f 100644 --- a/superset-frontend/src/explore/actions/saveModalActions.ts +++ b/superset-frontend/src/explore/actions/saveModalActions.ts @@ -119,19 +119,24 @@ export const getSlicePayload = ( } if (!hasTemporalRangeFilter(adhocFilters)) { - formDataWithNativeFilters.adhoc_filters?.forEach( - (filter: SimpleAdhocFilter) => { - if (filter.operator === Operators.TemporalRange && filter.isExtra) { - if (!adhocFilters.adhoc_filters) { - adhocFilters.adhoc_filters = []; - } - adhocFilters.adhoc_filters.push({ - ...filter, - comparator: 'No filter', - }); - } - }, + const adhocFiltersKeys = Object.keys(formDataWithNativeFilters).filter( + key => ADHOC_FILTER_REGEX.test(key), ); + adhocFiltersKeys?.forEach(filtersKey => { + formDataWithNativeFilters[filtersKey]?.forEach( + (filter: SimpleAdhocFilter) => { + if (filter.operator === Operators.TemporalRange && filter.isExtra) { + if (!adhocFilters[filtersKey]) { + adhocFilters[filtersKey] = []; + } + adhocFilters[filtersKey].push({ + ...filter, + comparator: 'No filter', + }); + } + }, + ); + }); } const formData = { ...formDataWithNativeFilters, From 55f18a34a95bdc7f7aaece9fe42cee5b78454f0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 10:50:02 -0600 Subject: [PATCH 15/23] build(deps): bump cookie, @applitools/eyes-storybook and express in /superset-frontend (#30572) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- superset-frontend/package-lock.json | 2177 ++++++++++++++++++--------- superset-frontend/package.json | 2 +- 2 files changed, 1508 insertions(+), 671 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 533829ac9bbc7..9c90f016f285b 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -145,7 +145,7 @@ "yargs": "^17.7.2" }, "devDependencies": { - "@applitools/eyes-storybook": "^3.50.7", + "@applitools/eyes-storybook": "^3.50.9", "@babel/cli": "^7.22.6", "@babel/compat-data": "^7.22.6", "@babel/core": "^7.23.9", @@ -274,7 +274,7 @@ "react-resizable": "^3.0.5", "react-test-renderer": "^16.14.0", "redux-mock-store": "^1.5.4", - "sinon": "^18.0.1", + "sinon": "^18.0.0", "source-map": "^0.7.4", "source-map-support": "^0.5.21", "speed-measure-webpack-plugin": "^1.5.0", @@ -395,22 +395,23 @@ } }, "node_modules/@applitools/core": { - "version": "4.18.0", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/@applitools/core/-/core-4.18.2.tgz", + "integrity": "sha512-loxNLlWyEdKBLTNUj4JUvDXImFxFVXZZ/NC/k5Z+LaXix3Xk5aIpCM+8Ii5Y96WBv8G7x/ZvQop7h823z3ai0Q==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@applitools/core-base": "1.16.0", - "@applitools/dom-capture": "11.3.0", + "@applitools/core-base": "1.16.1", + "@applitools/dom-capture": "11.4.0", "@applitools/dom-snapshot": "4.11.3", - "@applitools/driver": "1.18.0", - "@applitools/ec-client": "1.9.3", + "@applitools/driver": "1.19.0", + "@applitools/ec-client": "1.9.4", "@applitools/logger": "2.0.18", - "@applitools/nml-client": "1.8.9", + "@applitools/nml-client": "1.8.10", "@applitools/req": "1.7.2", - "@applitools/screenshoter": "3.8.35", + "@applitools/screenshoter": "3.8.36", "@applitools/snippets": "2.4.27", "@applitools/socket": "1.1.18", - "@applitools/spec-driver-webdriver": "1.1.11", + "@applitools/spec-driver-webdriver": "1.1.12", "@applitools/ufg-client": "1.12.3", "@applitools/utils": "1.7.4", "@types/ws": "8.5.5", @@ -431,9 +432,10 @@ } }, "node_modules/@applitools/core-base": { - "version": "1.16.0", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@applitools/core-base/-/core-base-1.16.1.tgz", + "integrity": "sha512-T4/BCba4b77lJRh85Ir9Gwc2cKKwzLAdrPOWbzwx2euhl7ZPUdd4U4ncQpv9uKTYFwz5zu3v5TCeUxrRpRtXqg==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/image": "1.1.13", "@applitools/logger": "2.0.18", @@ -448,8 +450,9 @@ }, "node_modules/@applitools/core/node_modules/semver": { "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -459,8 +462,9 @@ }, "node_modules/@applitools/core/node_modules/ws": { "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -479,8 +483,9 @@ }, "node_modules/@applitools/css-tree": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@applitools/css-tree/-/css-tree-1.1.4.tgz", + "integrity": "sha512-rH3aq/dkTweEUgS/MKuthD79CZDqpQVJlqmxqVxLZVAzbeFxYdTG/gnfG0zj6YJ025jzcPH2ktdW16Rl3QLutg==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "mdn-data": "2.1.0", "source-map-js": "1.0.1" @@ -491,16 +496,18 @@ }, "node_modules/@applitools/css-tree/node_modules/source-map-js": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", + "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/@applitools/dom-capture": { - "version": "11.3.0", + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@applitools/dom-capture/-/dom-capture-11.4.0.tgz", + "integrity": "sha512-8E5rjsuivGWx1TtZsjhwo32gF02dzwqvHf8NaN2fK+DTyomUvrh4QRD0ufUlKNeXIJhlVVgzjOkdfKjDj5pT/A==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/dom-shared": "1.0.15", "@applitools/functional-commons": "1.6.0" @@ -511,16 +518,18 @@ }, "node_modules/@applitools/dom-shared": { "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@applitools/dom-shared/-/dom-shared-1.0.15.tgz", + "integrity": "sha512-XN77SPfzXriU1x6gTcublSe0yUJHxlYwHesOnWQov2dMVfHx7y3qp0yrjdVC7LO2bDIJIzDlPJRhfg2otlbxig==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "engines": { "node": ">=12.13.0" } }, "node_modules/@applitools/dom-snapshot": { "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@applitools/dom-snapshot/-/dom-snapshot-4.11.3.tgz", + "integrity": "sha512-jdEWSbEOmD9LbzashTQ/YzYDdIKrhSBwNqNTIk8qjV8YtbQfZ+NtgCtW7nOsbknAMk95CfYEUV3R1rxCXs1XfA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/css-tree": "1.1.4", "@applitools/dom-shared": "1.0.15", @@ -532,9 +541,10 @@ } }, "node_modules/@applitools/driver": { - "version": "1.18.0", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@applitools/driver/-/driver-1.19.0.tgz", + "integrity": "sha512-fXNvT08/uR87Wi2nNURT9YXJYV/2ZG6DnKutk3jxsp29uNJXaHfruMXoA0p6guAWzo9gw592K0GKLTn1BB/3YA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/logger": "2.0.18", "@applitools/snippets": "2.4.27", @@ -547,8 +557,9 @@ }, "node_modules/@applitools/driver/node_modules/semver": { "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -557,17 +568,18 @@ } }, "node_modules/@applitools/ec-client": { - "version": "1.9.3", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@applitools/ec-client/-/ec-client-1.9.4.tgz", + "integrity": "sha512-PFuvt/XrJxzoy/fXeLTq+bE5+0mitV0whi4MUWZAnESIvHj3k3+oUUTZxPmRQEiR1zzxGvN7ar3sMQfiW+houA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@applitools/core-base": "1.16.0", - "@applitools/driver": "1.18.0", + "@applitools/core-base": "1.16.1", + "@applitools/driver": "1.19.0", "@applitools/logger": "2.0.18", "@applitools/req": "1.7.2", "@applitools/socket": "1.1.18", - "@applitools/spec-driver-webdriver": "1.1.11", - "@applitools/tunnel-client": "1.5.7", + "@applitools/spec-driver-webdriver": "1.1.12", + "@applitools/tunnel-client": "1.5.8", "@applitools/utils": "1.7.4", "abort-controller": "3.0.0", "webdriver": "7.31.1", @@ -583,16 +595,18 @@ }, "node_modules/@applitools/eg-frpc": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@applitools/eg-frpc/-/eg-frpc-1.0.5.tgz", + "integrity": "sha512-9qUNiCK3R3VKxIAaLr5HO5QnUx6TioLFkJ2JcpU1ZqefApt1X2bdfS7eA4TGDXDWv/a0OIl2Lddzuo5/h3vbTw==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "engines": { "node": ">=12.13.0" } }, "node_modules/@applitools/eg-socks5-proxy-server": { "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@applitools/eg-socks5-proxy-server/-/eg-socks5-proxy-server-0.5.6.tgz", + "integrity": "sha512-SjjDBFeiKspX3nHKOoSQ+l4JUiJK3xJiWAEaR8b+GuMvnGFLnrvAECHhuXXG00+LwBJM8WKmfxEe17nvZe+nhg==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "binary": "^0.3.0", "is-localhost-ip": "^2.0.0" @@ -602,16 +616,17 @@ } }, "node_modules/@applitools/execution-grid-tunnel": { - "version": "3.0.5", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@applitools/execution-grid-tunnel/-/execution-grid-tunnel-3.0.8.tgz", + "integrity": "sha512-4S6NcpxELH4NXketD3g6VUhWDUCuwAm4F1sCZdZLpPWOSMu5QwQDYUoe6/4t5KuktTQ4K7N90NmTzQrxiFtDKA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/eg-frpc": "1.0.5", "@applitools/eg-socks5-proxy-server": "^0.5.5", "@applitools/logger": "^1.0.12", "dotenv": "^16.0.0", "encoding": "^0.1.13", - "fastify": "^3.24.1", + "fastify": "^4.28.0", "fastify-plugin": "^3.0.1", "find-process": "^1.4.7", "ini": "^3.0.0", @@ -630,8 +645,9 @@ }, "node_modules/@applitools/execution-grid-tunnel/node_modules/@applitools/logger": { "version": "1.1.53", + "resolved": "https://registry.npmjs.org/@applitools/logger/-/logger-1.1.53.tgz", + "integrity": "sha512-4mlzYxc0MgM3WIxEwKqIjn9W7G7kMtQc2bFRxozViKOXypTfr72j8iODs88wcetP0GsXtplhZQ5/6aZN5WY9ug==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/utils": "1.3.36", "chalk": "4.1.2", @@ -643,16 +659,18 @@ }, "node_modules/@applitools/execution-grid-tunnel/node_modules/@applitools/utils": { "version": "1.3.36", + "resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.3.36.tgz", + "integrity": "sha512-eROEssh7wIW+V87PvLiHI2hUPxqoBxXFMRx3+z5qOZqXUPSR1Uz7EMFwxZcDDR7T6C3O3UDckB2aVB5fJAg5JA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "engines": { "node": ">=12.13.0" } }, "node_modules/@applitools/execution-grid-tunnel/node_modules/debug": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -667,41 +685,45 @@ }, "node_modules/@applitools/execution-grid-tunnel/node_modules/ini": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", + "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", "dev": true, - "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@applitools/execution-grid-tunnel/node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/@applitools/execution-grid-tunnel/node_modules/uuid": { "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/@applitools/eyes-storybook": { - "version": "3.50.7", + "version": "3.50.9", + "resolved": "https://registry.npmjs.org/@applitools/eyes-storybook/-/eyes-storybook-3.50.9.tgz", + "integrity": "sha512-Zxp6cbLExsFkcoz0h1cAhJR5Ye8pXhnvBspwuaPxL437Lt1dowlCLlPkZx5LWSB9LD3u0RVdXhuE61ONPHE02A==", "dev": true, "hasInstallScript": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@applitools/core": "4.18.0", - "@applitools/driver": "1.18.0", + "@applitools/core": "4.18.2", + "@applitools/driver": "1.19.0", "@applitools/functional-commons": "1.6.0", "@applitools/logger": "2.0.18", "@applitools/monitoring-commons": "1.0.19", - "@applitools/spec-driver-puppeteer": "1.4.11", + "@applitools/spec-driver-puppeteer": "1.4.12", "@applitools/ufg-client": "1.12.3", "@applitools/utils": "1.7.4", "boxen": "4.2.0", @@ -937,16 +959,18 @@ }, "node_modules/@applitools/functional-commons": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@applitools/functional-commons/-/functional-commons-1.6.0.tgz", + "integrity": "sha512-fwiF0CbeYHDEOTD/NKaFgaI8LvRcGYG2GaJJiRwcedKko16sQ8F3TK5wXfj2Ytjf+8gjwHwsEEX550z3yvDWxA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=8.0.0" } }, "node_modules/@applitools/image": { "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@applitools/image/-/image-1.1.13.tgz", + "integrity": "sha512-oeSnsTJxhD6juNlWufeWsiWV9dbS0a3OL75/r/Bo2yauAi6AsRMDeh+McXJfYlf1NVZbrVG0+vNXn52mDVEIyw==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/utils": "1.7.4", "bmpimagejs": "1.0.4", @@ -960,8 +984,9 @@ }, "node_modules/@applitools/logger": { "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@applitools/logger/-/logger-2.0.18.tgz", + "integrity": "sha512-d54OTreCXE+G9qUxiPDHHBzwof3EnXPrADdZ7ToB9AoI+kOgs/v6wjMx0ghAoXyyOiLvlvJnmdHSyJssRdv5GA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/utils": "1.7.4", "chalk": "4.1.2", @@ -973,8 +998,9 @@ }, "node_modules/@applitools/logger/node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -989,8 +1015,9 @@ }, "node_modules/@applitools/logger/node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/@applitools/monitoring-commons": { "version": "1.0.19", @@ -1025,9 +1052,10 @@ "license": "MIT" }, "node_modules/@applitools/nml-client": { - "version": "1.8.9", + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/@applitools/nml-client/-/nml-client-1.8.10.tgz", + "integrity": "sha512-avoZnD39XrWJg5x7PiFv+58YEDLbWPRIb+dHrH9LVD1HcQC8tmht2KfVLnTJLJtJgRQojqZh5H8rmplfT46t8w==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/logger": "2.0.18", "@applitools/req": "1.7.2", @@ -1039,8 +1067,9 @@ }, "node_modules/@applitools/req": { "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@applitools/req/-/req-1.7.2.tgz", + "integrity": "sha512-L0tjPFGEJFAEGaifqtmtCghjkG7M0wnEwfzbHi6O+ThtTCbg4JSDRTaNvA+PLXQoS0mFvajG40/t5a4EgAG7QQ==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/utils": "1.7.4", "abort-controller": "3.0.0", @@ -1054,16 +1083,18 @@ }, "node_modules/@applitools/req/node_modules/data-uri-to-buffer": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 12" } }, "node_modules/@applitools/req/node_modules/node-fetch": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", + "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", "dev": true, - "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -1078,9 +1109,10 @@ } }, "node_modules/@applitools/screenshoter": { - "version": "3.8.35", + "version": "3.8.36", + "resolved": "https://registry.npmjs.org/@applitools/screenshoter/-/screenshoter-3.8.36.tgz", + "integrity": "sha512-bzl+fs3c4L6J2t/PELxmoMGc40ZvjaExD0PMM6GvbNp3uPbDtGS348DC1ZYsSl481OxTae/uiO/iVOQP4bNZCQ==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/image": "1.1.13", "@applitools/logger": "2.0.18", @@ -1093,16 +1125,18 @@ }, "node_modules/@applitools/snippets": { "version": "2.4.27", + "resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.4.27.tgz", + "integrity": "sha512-n6ckwbXWyJ+/DoV1T6bRiGXITgTgjayV0j4AzHiBx+HF3JdzygxIkWtn7yl1dJfzeqEGyrtBK6Sq1tTG2GoQcA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "engines": { "node": ">=12.13.0" } }, "node_modules/@applitools/socket": { "version": "1.1.18", + "resolved": "https://registry.npmjs.org/@applitools/socket/-/socket-1.1.18.tgz", + "integrity": "sha512-EMI/MMfVH38ucuZhFWOTUR8cPvuoP9b+xi5yBJF8uLlJjxQEmGnvm+Pm3s9o3mfxQzDRddYGtpIo3TTZhMVZdQ==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/logger": "2.0.18", "@applitools/utils": "1.7.4" @@ -1112,11 +1146,12 @@ } }, "node_modules/@applitools/spec-driver-puppeteer": { - "version": "1.4.11", + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/@applitools/spec-driver-puppeteer/-/spec-driver-puppeteer-1.4.12.tgz", + "integrity": "sha512-ap0H3ooVjkpGXlsjQSNJKV8uZLyTyIbEL/63snts1b3W+7wu3q884j1MI0bCW/ZOHotYeeAoqkKQ9exdDIowjw==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@applitools/driver": "1.18.0", + "@applitools/driver": "1.19.0", "@applitools/utils": "1.7.4" }, "engines": { @@ -1127,11 +1162,12 @@ } }, "node_modules/@applitools/spec-driver-webdriver": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@applitools/spec-driver-webdriver/-/spec-driver-webdriver-1.1.12.tgz", + "integrity": "sha512-r6PobChadcc3couBtnf3pTunL7Vi00cNcg2l1rTr0ApSEfJ1m1DdTcX8bgXU1jDzJ2QhCn7OoqsziTajQdWmoA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@applitools/driver": "1.18.0", + "@applitools/driver": "1.19.0", "@applitools/utils": "1.7.4", "http-proxy-agent": "5.0.0", "https-proxy-agent": "5.0.1" @@ -1144,11 +1180,12 @@ } }, "node_modules/@applitools/tunnel-client": { - "version": "1.5.7", + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@applitools/tunnel-client/-/tunnel-client-1.5.8.tgz", + "integrity": "sha512-SJByl2/I0NftENw5NvW+nHN+Vq64b0aeTsdCTYKhDhJBWqPEkGYwRR5ziYpk8MWYsL2hWcPUfg/S/hS+M3zmDg==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@applitools/execution-grid-tunnel": "3.0.5", + "@applitools/execution-grid-tunnel": "3.0.8", "@applitools/logger": "2.0.18", "@applitools/req": "1.7.2", "@applitools/socket": "1.1.18", @@ -1165,8 +1202,9 @@ }, "node_modules/@applitools/ufg-client": { "version": "1.12.3", + "resolved": "https://registry.npmjs.org/@applitools/ufg-client/-/ufg-client-1.12.3.tgz", + "integrity": "sha512-bSxLqxzAuc+ldum/nGoiM/iCcf97uku3bABxB90ilzUYT1DOu9vEGmaPxxGLDc+GRRVYlOYGNdIJF+DQP4dFTg==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "dependencies": { "@applitools/css-tree": "1.1.4", "@applitools/image": "1.1.13", @@ -1183,8 +1221,9 @@ }, "node_modules/@applitools/utils": { "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.7.4.tgz", + "integrity": "sha512-qgJqx2yjlJBf79YyFehf1nSp4AXOdzJn3POQyg8CMWV0YH6HsjAfJjYaNrbXFcGYCSpPEJGhGehxC7GVKHX3YA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", "engines": { "node": ">=12.13.0" } @@ -5397,17 +5436,73 @@ "license": "MIT" }, "node_modules/@fastify/ajv-compiler": { - "version": "1.1.0", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz", + "integrity": "sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==", + "dev": true, + "dependencies": { + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "fast-uri": "^2.0.0" + } + }, + "node_modules/@fastify/ajv-compiler/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "license": "MIT", "dependencies": { - "ajv": "^6.12.6" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@fastify/ajv-compiler/node_modules/ajv/node_modules/fast-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", + "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "dev": true + }, + "node_modules/@fastify/ajv-compiler/node_modules/fast-uri": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", + "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==", + "dev": true + }, + "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/@fastify/error": { - "version": "2.0.0", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.4.1.tgz", + "integrity": "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==", + "dev": true + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", + "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", "dev": true, - "license": "MIT" + "dependencies": { + "fast-json-stringify": "^5.7.0" + } + }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", + "integrity": "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + } }, "node_modules/@fontsource/fira-code": { "version": "5.0.18", @@ -8886,8 +8981,9 @@ }, "node_modules/@puppeteer/browsers": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", + "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "debug": "^4.3.5", "extract-zip": "^2.0.1", @@ -8906,11 +9002,12 @@ } }, "node_modules/@puppeteer/browsers/node_modules/debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -8922,14 +9019,16 @@ } }, "node_modules/@puppeteer/browsers/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/@puppeteer/browsers/node_modules/semver": { "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -9655,8 +9754,9 @@ }, "node_modules/@sindresorhus/is": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -12877,8 +12977,9 @@ }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, - "license": "MIT", "dependencies": { "defer-to-connect": "^2.0.0" }, @@ -13050,8 +13151,9 @@ }, "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true }, "node_modules/@tsconfig/node10": { "version": "1.0.8", @@ -13250,8 +13352,9 @@ }, "node_modules/@types/cacheable-request": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dev": true, - "license": "MIT", "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", @@ -13483,8 +13586,9 @@ }, "node_modules/@types/glob": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", "dev": true, - "license": "MIT", "dependencies": { "@types/minimatch": "^5.1.2", "@types/node": "*" @@ -13499,8 +13603,9 @@ }, "node_modules/@types/glob/node_modules/@types/minimatch": { "version": "5.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true }, "node_modules/@types/graceful-fs": { "version": "4.1.3", @@ -13668,8 +13773,9 @@ }, "node_modules/@types/keyv": { "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -13930,8 +14036,9 @@ }, "node_modules/@types/responselike": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -15355,8 +15462,9 @@ }, "node_modules/@wdio/config": { "version": "7.31.1", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.31.1.tgz", + "integrity": "sha512-WAfswbCatwiaDVqy6kfF/5T8/WS/US/SRhBGUFrfBuGMIe+RRoHgy7jURFWSvUIE7CNHj8yvs46fLUcxhXjzcQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/glob": "^8.1.0", "@wdio/logger": "7.26.0", @@ -15369,54 +15477,30 @@ "node": ">=12.0.0" } }, - "node_modules/@wdio/config/node_modules/@types/node": { - "version": "18.19.42", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@wdio/config/node_modules/@wdio/types": { - "version": "7.30.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "^18.0.0", - "got": "^11.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "^4.6.2" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@wdio/config/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@wdio/config/node_modules/deepmerge": { "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" } }, "node_modules/@wdio/config/node_modules/glob": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15433,8 +15517,9 @@ }, "node_modules/@wdio/config/node_modules/minimatch": { "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -15444,8 +15529,9 @@ }, "node_modules/@wdio/logger": { "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.26.0.tgz", + "integrity": "sha512-kQj9s5JudAG9qB+zAAcYGPHVfATl2oqKgqj47yjehOQ1zzG33xmtL1ArFbQKWhDG32y1A8sN6b0pIqBEIwgg8Q==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.0.0", "loglevel": "^1.6.0", @@ -15458,51 +15544,55 @@ }, "node_modules/@wdio/protocols": { "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.27.0.tgz", + "integrity": "sha512-hT/U22R5i3HhwPjkaKAG0yd59eaOaZB0eibRj2+esCImkb5Y6rg8FirrlYRxIGFVBl0+xZV0jKHzR5+o097nvg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12.0.0" } }, - "node_modules/@wdio/utils": { + "node_modules/@wdio/types": { "version": "7.30.2", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", + "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, - "license": "MIT", "dependencies": { - "@wdio/logger": "7.26.0", - "@wdio/types": "7.30.2", - "p-iteration": "^1.1.8" + "@types/node": "^18.0.0", + "got": "^11.8.1" }, "engines": { "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "^4.6.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@wdio/utils/node_modules/@types/node": { - "version": "18.19.42", + "node_modules/@wdio/types/node_modules/@types/node": { + "version": "18.19.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.55.tgz", + "integrity": "sha512-zzw5Vw52205Zr/nmErSEkN5FLqXPuKX/k5d1D7RKHATGqU7y6YfX9QxZraUzUrFGqH6XzOzG196BC35ltJC4Cw==", "dev": true, - "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@wdio/utils/node_modules/@wdio/types": { + "node_modules/@wdio/utils": { "version": "7.30.2", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.30.2.tgz", + "integrity": "sha512-np7I+smszFUennbQKdzbMN/zUL3s3EZq9pCCUcTRjjs9TE4tnn0wfmGdoz2o7REYu6kn9NfFFJyVIM2VtBbKEA==", "dev": true, - "license": "MIT", "dependencies": { - "@types/node": "^18.0.0", - "got": "^11.8.1" + "@wdio/logger": "7.26.0", + "@wdio/types": "7.30.2", + "p-iteration": "^1.1.8" }, "engines": { "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "^4.6.2" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, "node_modules/@webassemblyjs/ast": { @@ -15671,8 +15761,9 @@ }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -15930,8 +16021,9 @@ }, "node_modules/abstract-logging": { "version": "2.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "dev": true }, "node_modules/accepts": { "version": "1.3.8", @@ -16880,7 +16972,8 @@ "node_modules/archy": { "version": "1.0.0", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/arg": { "version": "4.1.3", @@ -17276,8 +17369,9 @@ }, "node_modules/atomic-sleep": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -17293,37 +17387,15 @@ } }, "node_modules/avvio": { - "version": "7.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "archy": "^1.0.0", - "debug": "^4.0.0", - "fastq": "^1.6.1", - "queue-microtask": "^1.1.2" - } - }, - "node_modules/avvio/node_modules/debug": { - "version": "4.3.6", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.4.0.tgz", + "integrity": "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "@fastify/error": "^3.3.0", + "fastq": "^1.17.1" } }, - "node_modules/avvio/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, "node_modules/aws-sign2": { "version": "0.7.0", "dev": true, @@ -17890,9 +17962,10 @@ "optional": true }, "node_modules/bare-fs": { - "version": "2.3.1", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", "dev": true, - "license": "Apache-2.0", "optional": true, "dependencies": { "bare-events": "^2.0.0", @@ -17901,27 +17974,31 @@ } }, "node_modules/bare-os": { - "version": "2.4.0", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", "dev": true, - "license": "Apache-2.0", "optional": true }, "node_modules/bare-path": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", "dev": true, - "license": "Apache-2.0", "optional": true, "dependencies": { "bare-os": "^2.1.0" } }, "node_modules/bare-stream": { - "version": "2.1.3", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz", + "integrity": "sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==", "dev": true, - "license": "Apache-2.0", "optional": true, "dependencies": { - "streamx": "^2.18.0" + "b4a": "^1.6.6", + "streamx": "^2.20.0" } }, "node_modules/base": { @@ -18019,8 +18096,9 @@ }, "node_modules/basic-ftp": { "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -18143,11 +18221,15 @@ }, "node_modules/binary": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", "dev": true, - "license": "MIT", "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" } }, "node_modules/binary-extensions": { @@ -18221,8 +18303,9 @@ }, "node_modules/bmpimagejs": { "version": "1.0.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/bmpimagejs/-/bmpimagejs-1.0.4.tgz", + "integrity": "sha512-21oKU7kbRt2OgOOj7rdiNr/yznDNUQ585plxR00rsmECcZr+6O1oCwB8OIoSHk/bDhbG8mFXIdeQuCPHgZ6QBw==", + "dev": true }, "node_modules/body-parser": { "version": "1.20.3", @@ -18515,6 +18598,8 @@ }, "node_modules/buffers": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", "dev": true, "engines": { "node": ">=0.2.0" @@ -18773,16 +18858,18 @@ }, "node_modules/cacheable-lookup": { "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.6.0" } }, "node_modules/cacheable-request": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, - "license": "MIT", "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -18798,8 +18885,9 @@ }, "node_modules/cacheable-request/node_modules/get-stream": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, - "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -18992,16 +19080,24 @@ }, "node_modules/chainsaw": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", "dev": true, - "license": "MIT/X11", "dependencies": { "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" } }, "node_modules/chainsaw/node_modules/traverse": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", "dev": true, - "license": "MIT/X11" + "engines": { + "node": "*" + } }, "node_modules/chalk": { "version": "4.1.2", @@ -19228,8 +19324,9 @@ }, "node_modules/chromium-bidi": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", + "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", "dev": true, - "license": "Apache-2.0", "dependencies": { "mitt": "3.0.1", "urlpattern-polyfill": "10.0.0", @@ -19241,8 +19338,9 @@ }, "node_modules/chromium-bidi/node_modules/mitt": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true }, "node_modules/chrono-node": { "version": "2.7.6", @@ -19474,8 +19572,9 @@ }, "node_modules/clone-response": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "dev": true, - "license": "MIT", "dependencies": { "mimic-response": "^1.0.0" }, @@ -20096,9 +20195,10 @@ } }, "node_modules/cookie": { - "version": "0.5.0", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -21450,8 +21550,9 @@ }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 14" } @@ -22065,8 +22166,9 @@ }, "node_modules/degenerator": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, - "license": "MIT", "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -22078,8 +22180,9 @@ }, "node_modules/degenerator/node_modules/ast-types": { "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -22089,8 +22192,9 @@ }, "node_modules/degenerator/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", @@ -22109,8 +22213,9 @@ }, "node_modules/degenerator/node_modules/esprima": { "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", "esvalidate": "bin/esvalidate.js" @@ -22121,25 +22226,28 @@ }, "node_modules/degenerator/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/degenerator/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/degenerator/node_modules/tslib": { - "version": "2.6.3", - "dev": true, - "license": "0BSD" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true }, "node_modules/delaunator": { "version": "5.0.0", @@ -22368,8 +22476,9 @@ }, "node_modules/devtools-protocol": { "version": "0.0.1312386", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz", + "integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==", + "dev": true }, "node_modules/diff": { "version": "4.0.2", @@ -25077,9 +25186,9 @@ } }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, "dependencies": { "accepts": "~1.3.8", @@ -25087,7 +25196,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -25124,9 +25233,10 @@ "license": "MIT" }, "node_modules/express/node_modules/cookie": { - "version": "0.6.0", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -25430,13 +25540,15 @@ }, "node_modules/fast-content-type-parse": { "version": "1.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", + "integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==", + "dev": true }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "dev": true }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -25529,35 +25641,89 @@ "license": "MIT" }, "node_modules/fast-json-stringify": { - "version": "2.7.13", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", + "integrity": "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==", "dev": true, - "license": "MIT", "dependencies": { - "ajv": "^6.11.0", - "deepmerge": "^4.2.2", - "rfdc": "^1.2.0", - "string-similarity": "^4.0.1" + "@fastify/merge-json-schemas": "^0.1.0", + "ajv": "^8.10.0", + "ajv-formats": "^3.0.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^2.1.0", + "json-schema-ref-resolver": "^1.0.1", + "rfdc": "^1.2.0" + } + }, + "node_modules/fast-json-stringify/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">= 10.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/fast-json-stringify/node_modules/deepmerge": { - "version": "4.3.1", + "node_modules/fast-json-stringify/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, + "node_modules/fast-json-stringify/node_modules/ajv/node_modules/fast-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", + "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "dev": true + }, + "node_modules/fast-json-stringify/node_modules/fast-uri": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", + "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==", + "dev": true + }, + "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/fast-levenshtein": { "version": "2.0.6", "license": "MIT" }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "dev": true, + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, "node_modules/fast-redact": { "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -25597,37 +25763,50 @@ "license": "MIT" }, "node_modules/fastify": { - "version": "3.29.5", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.28.1.tgz", + "integrity": "sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==", "dev": true, - "license": "MIT", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "dependencies": { - "@fastify/ajv-compiler": "^1.0.0", - "@fastify/error": "^2.0.0", - "abstract-logging": "^2.0.0", - "avvio": "^7.1.2", - "fast-content-type-parse": "^1.0.0", - "fast-json-stringify": "^2.5.2", - "find-my-way": "^4.5.0", - "flatstr": "^1.0.12", - "light-my-request": "^4.2.0", - "pino": "^6.13.0", - "process-warning": "^1.0.0", + "@fastify/ajv-compiler": "^3.5.0", + "@fastify/error": "^3.4.0", + "@fastify/fast-json-stringify-compiler": "^4.3.0", + "abstract-logging": "^2.0.1", + "avvio": "^8.3.0", + "fast-content-type-parse": "^1.1.0", + "fast-json-stringify": "^5.8.0", + "find-my-way": "^8.0.0", + "light-my-request": "^5.11.0", + "pino": "^9.0.0", + "process-warning": "^3.0.0", "proxy-addr": "^2.0.7", - "rfdc": "^1.1.4", - "secure-json-parse": "^2.0.0", - "semver": "^7.3.2", - "tiny-lru": "^8.0.1" + "rfdc": "^1.3.0", + "secure-json-parse": "^2.7.0", + "semver": "^7.5.4", + "toad-cache": "^3.3.0" } }, "node_modules/fastify-plugin": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-3.0.1.tgz", + "integrity": "sha512-qKcDXmuZadJqdTm6vlCqioEbyewF60b/0LOFCcYN1B6BIZGlYJumWWOYs70SFYLDAH4YqdE1cxH/RKMG7rFxgA==", + "dev": true }, "node_modules/fastify/node_modules/semver": { "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -25636,8 +25815,9 @@ } }, "node_modules/fastq": { - "version": "1.8.0", - "license": "ISC", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dependencies": { "reusify": "^1.0.4" } @@ -25933,23 +26113,24 @@ } }, "node_modules/find-my-way": { - "version": "4.5.1", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.2.tgz", + "integrity": "sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==", "dev": true, - "license": "MIT", "dependencies": { - "fast-decode-uri-component": "^1.0.1", "fast-deep-equal": "^3.1.3", - "safe-regex2": "^2.0.0", - "semver-store": "^0.3.0" + "fast-querystring": "^1.0.0", + "safe-regex2": "^3.1.0" }, "engines": { - "node": ">=10" + "node": ">=14" } }, "node_modules/find-process": { "version": "1.4.7", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.7.tgz", + "integrity": "sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.0.0", "commander": "^5.1.0", @@ -25961,18 +26142,20 @@ }, "node_modules/find-process/node_modules/commander": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/find-process/node_modules/debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -25984,9 +26167,10 @@ } }, "node_modules/find-process/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/find-root": { "version": "1.1.0", @@ -26049,11 +26233,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/flatstr": { - "version": "1.0.12", - "dev": true, - "license": "MIT" - }, "node_modules/flatted": { "version": "3.1.0", "dev": true, @@ -26912,8 +27091,9 @@ }, "node_modules/get-uri": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dev": true, - "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", @@ -26925,11 +27105,12 @@ } }, "node_modules/get-uri/node_modules/debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -26941,9 +27122,10 @@ } }, "node_modules/get-uri/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/get-value": { "version": "2.0.6", @@ -27495,8 +27677,9 @@ }, "node_modules/got": { "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, - "license": "MIT", "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", @@ -28667,8 +28850,9 @@ }, "node_modules/http2-wrapper": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "dev": true, - "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" @@ -28679,8 +28863,9 @@ }, "node_modules/http2-wrapper/node_modules/quick-lru": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -29542,8 +29727,9 @@ }, "node_modules/is-localhost-ip": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-localhost-ip/-/is-localhost-ip-2.0.0.tgz", + "integrity": "sha512-vlgs2cSgMOfnKU8c1ewgKPyum9rVrjjLLW2HBdL5i0iAJjOs8NY55ZBd/hqUTaYR0EO9CKZd3hVSC2HlIbygTQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" } @@ -32466,8 +32652,9 @@ }, "node_modules/jpeg-js": { "version": "0.4.4", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "dev": true }, "node_modules/jquery": { "version": "3.7.1", @@ -32953,6 +33140,15 @@ "node": ">=12.0.0" } }, + "node_modules/json-schema-ref-resolver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", + "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "devOptional": true, @@ -33139,8 +33335,9 @@ }, "node_modules/ky": { "version": "0.30.0", + "resolved": "https://registry.npmjs.org/ky/-/ky-0.30.0.tgz", + "integrity": "sha512-X/u76z4JtDVq10u1JA5UQfatPxgPaVDMYTrgHyiTpGN2z4TMEJkIHsoSBBSg9SWZEIXTKsi9kHgiQ9o3Y/4yog==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -34093,36 +34290,16 @@ } }, "node_modules/light-my-request": { - "version": "4.12.0", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.14.0.tgz", + "integrity": "sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "ajv": "^8.1.0", - "cookie": "^0.5.0", - "process-warning": "^1.0.0", + "cookie": "^0.7.0", + "process-warning": "^3.0.0", "set-cookie-parser": "^2.4.1" } }, - "node_modules/light-my-request/node_modules/ajv": { - "version": "8.17.1", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/light-my-request/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/lilconfig": { "version": "3.0.0", "dev": true, @@ -34377,9 +34554,10 @@ } }, "node_modules/loglevel": { - "version": "1.9.1", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6.0" }, @@ -34390,8 +34568,9 @@ }, "node_modules/loglevel-plugin-prefix": { "version": "0.8.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", + "dev": true }, "node_modules/long": { "version": "3.2.0", @@ -34431,8 +34610,9 @@ }, "node_modules/lowercase-keys": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -38056,8 +38236,9 @@ }, "node_modules/mdn-data": { "version": "2.1.0", - "dev": true, - "license": "CC0-1.0" + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.1.0.tgz", + "integrity": "sha512-dbAWH6A+2NGuVJlQFrTKHJc07Vqn5frnhyTOGz+7BsK7V2hHdoBcwoiyV3QVhLHYpM/zqe2OSUn5ZWbVXLBB8A==", + "dev": true }, "node_modules/media-typer": { "version": "0.3.0", @@ -39745,8 +39926,9 @@ }, "node_modules/mimic-response": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -40341,8 +40523,9 @@ }, "node_modules/netmask": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -40390,8 +40573,9 @@ }, "node_modules/node-cleanup": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", + "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", + "dev": true }, "node_modules/node-dir": { "version": "0.1.17", @@ -40861,8 +41045,9 @@ }, "node_modules/normalize-url": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -41951,13 +42136,23 @@ }, "node_modules/omggif": { "version": "1.0.10", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", + "dev": true }, "node_modules/omit.js": { "version": "2.0.2", "license": "MIT" }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/on-finished": { "version": "2.4.1", "dev": true, @@ -42139,8 +42334,9 @@ }, "node_modules/p-cancelable": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -42155,8 +42351,9 @@ }, "node_modules/p-iteration": { "version": "1.1.8", + "resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz", + "integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -42292,8 +42489,9 @@ }, "node_modules/pac-proxy-agent": { "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", "dev": true, - "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", @@ -42310,8 +42508,9 @@ }, "node_modules/pac-proxy-agent/node_modules/agent-base": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -42320,11 +42519,12 @@ } }, "node_modules/pac-proxy-agent/node_modules/debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -42337,8 +42537,9 @@ }, "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { "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": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -42349,8 +42550,9 @@ }, "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -42360,14 +42562,16 @@ } }, "node_modules/pac-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/pac-resolver": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, - "license": "MIT", "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -42625,8 +42829,9 @@ }, "node_modules/pako": { "version": "1.0.11", - "dev": true, - "license": "(MIT AND Zlib)" + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true }, "node_modules/param-case": { "version": "3.0.4", @@ -43036,26 +43241,126 @@ } }, "node_modules/pino": { - "version": "6.14.0", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.4.0.tgz", + "integrity": "sha512-nbkQb5+9YPhQRz/BeQmrWpEknAaqjpAqRK8NwJpmrX/JHu7JuZC5G1CeAwJDJfGes4h+YihC6in3Q2nGb+Y09w==", "dev": true, - "license": "MIT", "dependencies": { - "fast-redact": "^3.0.0", - "fast-safe-stringify": "^2.0.8", - "flatstr": "^1.0.12", - "pino-std-serializers": "^3.1.0", - "process-warning": "^1.0.0", + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^4.0.0", "quick-format-unescaped": "^4.0.3", - "sonic-boom": "^1.0.2" + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, - "node_modules/pino-std-serializers": { - "version": "3.2.0", + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", "dev": true, - "license": "MIT" + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/pino-abstract-transport/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/pino-abstract-transport/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "dev": true + }, + "node_modules/pino/node_modules/process-warning": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.0.tgz", + "integrity": "sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==", + "dev": true }, "node_modules/pirates": { "version": "4.0.6", @@ -43149,8 +43454,9 @@ }, "node_modules/png-async": { "version": "0.9.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/png-async/-/png-async-0.9.4.tgz", + "integrity": "sha512-B//AXX9TkneKfgtOpT1mdUnnhk2BImGD+a98vImsMU8uo1dBeHyW/kM2erWZ/CsYteTPU/xKG+t6T62heHkC3A==", + "dev": true }, "node_modules/po2json": { "version": "0.4.5", @@ -43879,9 +44185,10 @@ } }, "node_modules/process-warning": { - "version": "1.0.0", - "dev": true, - "license": "MIT" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", + "dev": true }, "node_modules/proggy": { "version": "2.0.0", @@ -43893,8 +44200,9 @@ }, "node_modules/progress": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -44047,8 +44355,9 @@ }, "node_modules/proxy-agent": { "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -44065,8 +44374,9 @@ }, "node_modules/proxy-agent/node_modules/agent-base": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -44075,11 +44385,12 @@ } }, "node_modules/proxy-agent/node_modules/debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -44092,8 +44403,9 @@ }, "node_modules/proxy-agent/node_modules/http-proxy-agent": { "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": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -44104,8 +44416,9 @@ }, "node_modules/proxy-agent/node_modules/https-proxy-agent": { "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -44116,21 +44429,24 @@ }, "node_modules/proxy-agent/node_modules/lru-cache": { "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, - "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/proxy-agent/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/proxy-agent/node_modules/proxy-from-env": { "version": "1.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true }, "node_modules/proxy-from-env": { "version": "1.0.0", @@ -44185,9 +44501,10 @@ }, "node_modules/puppeteer": { "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.15.0.tgz", + "integrity": "sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==", "dev": true, "hasInstallScript": true, - "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.3.0", "cosmiconfig": "^9.0.0", @@ -44203,8 +44520,9 @@ }, "node_modules/puppeteer-core": { "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", + "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.3.0", "chromium-bidi": "0.6.3", @@ -44217,11 +44535,12 @@ } }, "node_modules/puppeteer-core/node_modules/debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -44233,14 +44552,16 @@ } }, "node_modules/puppeteer-core/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/puppeteer-core/node_modules/ws": { "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -44259,13 +44580,15 @@ }, "node_modules/puppeteer/node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/puppeteer/node_modules/cosmiconfig": { "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, - "license": "MIT", "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -44289,8 +44612,9 @@ }, "node_modules/puppeteer/node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -44300,8 +44624,9 @@ }, "node_modules/puppeteer/node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -44400,8 +44725,9 @@ }, "node_modules/quick-format-unescaped": { "version": "4.0.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "dev": true }, "node_modules/quick-lru": { "version": "4.0.1", @@ -46354,6 +46680,15 @@ "node": ">= 6" } }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/realpath-native": { "version": "1.1.0", "dev": true, @@ -47975,8 +48310,9 @@ }, "node_modules/responselike": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, - "license": "MIT", "dependencies": { "lowercase-keys": "^2.0.0" }, @@ -48022,8 +48358,9 @@ }, "node_modules/rfdc": { "version": "1.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true }, "node_modules/rimraf": { "version": "6.0.1", @@ -48344,19 +48681,30 @@ } }, "node_modules/safe-regex2": { - "version": "2.0.0", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz", + "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==", "dev": true, - "license": "MIT", "dependencies": { - "ret": "~0.2.0" + "ret": "~0.4.0" } }, "node_modules/safe-regex2/node_modules/ret": { - "version": "0.2.2", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz", + "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "dev": true, + "engines": { + "node": ">=10" } }, "node_modules/safer-buffer": { @@ -48424,8 +48772,9 @@ }, "node_modules/secure-json-parse": { "version": "2.7.0", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "dev": true }, "node_modules/seedrandom": { "version": "3.0.5", @@ -48455,11 +48804,6 @@ "semver": "bin/semver" } }, - "node_modules/semver-store": { - "version": "0.3.0", - "dev": true, - "license": "MIT" - }, "node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -48598,9 +48942,10 @@ "license": "ISC" }, "node_modules/set-cookie-parser": { - "version": "2.6.0", - "dev": true, - "license": "MIT" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", + "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==", + "dev": true }, "node_modules/set-function-length": { "version": "1.2.1", @@ -49159,12 +49504,12 @@ "license": "MIT" }, "node_modules/sonic-boom": { - "version": "1.4.1", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.1.0.tgz", + "integrity": "sha512-NGipjjRicyJJ03rPiZCJYjwlsuP2d1/5QUviozRXC7S3WdVWNK5e3Ojieb9CCyfhq2UC+3+SRd9nG3I2lPRvUw==", "dev": true, - "license": "MIT", "dependencies": { - "atomic-sleep": "^1.0.0", - "flatstr": "^1.0.12" + "atomic-sleep": "^1.0.0" } }, "node_modules/sort-keys": { @@ -49879,8 +50224,9 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.18.0", - "license": "MIT", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", @@ -49924,11 +50270,6 @@ "node": ">=10" } }, - "node_modules/string-similarity": { - "version": "4.0.4", - "dev": true, - "license": "ISC" - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -50362,8 +50703,9 @@ }, "node_modules/tar-fs": { "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, - "license": "MIT", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -50375,8 +50717,9 @@ }, "node_modules/tar-fs/node_modules/tar-stream": { "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, - "license": "MIT", "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", @@ -50445,11 +50788,12 @@ }, "node_modules/teen_process": { "version": "1.16.0", + "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-1.16.0.tgz", + "integrity": "sha512-RnW7HHZD1XuhSTzD3djYOdIl1adE3oNEprE3HOFFxWs5m4FZsqYRhKJ4mDU2udtNGMLUS7jV7l8vVRLWAvmPDw==", "dev": true, "engines": [ "node" ], - "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.0.0", "bluebird": "^3.5.1", @@ -50461,8 +50805,9 @@ }, "node_modules/teen_process/node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -50784,10 +51129,20 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "dev": true, + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/throat": { "version": "6.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", + "dev": true }, "node_modules/throttle-debounce": { "version": "5.0.2", @@ -50833,14 +51188,6 @@ "version": "1.3.3", "license": "MIT" }, - "node_modules/tiny-lru": { - "version": "8.0.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=6" - } - }, "node_modules/tiny-warning": { "version": "1.0.3", "license": "MIT" @@ -50964,6 +51311,15 @@ "node": ">=0.10.0" } }, + "node_modules/toad-cache": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", + "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/tocbot": { "version": "4.28.2", "license": "MIT" @@ -51543,8 +51899,9 @@ }, "node_modules/unbzip2-stream": { "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, - "license": "MIT", "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -51948,8 +52305,9 @@ }, "node_modules/urlpattern-polyfill": { "version": "10.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true }, "node_modules/use": { "version": "3.1.1", @@ -52434,8 +52792,9 @@ }, "node_modules/webdriver": { "version": "7.31.1", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.31.1.tgz", + "integrity": "sha512-nCdJLxRnYvOMFqTEX7sqQtF/hV/Jgov0Y6ICeOm1DMTlZSRRDaUsBMlEAPkEwif9uBJYdM0znv8qzfX358AGqQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "^18.0.0", "@wdio/config": "7.31.1", @@ -52452,33 +52811,14 @@ } }, "node_modules/webdriver/node_modules/@types/node": { - "version": "18.19.42", + "version": "18.19.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.55.tgz", + "integrity": "sha512-zzw5Vw52205Zr/nmErSEkN5FLqXPuKX/k5d1D7RKHATGqU7y6YfX9QxZraUzUrFGqH6XzOzG196BC35ltJC4Cw==", "dev": true, - "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/webdriver/node_modules/@wdio/types": { - "version": "7.30.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "^18.0.0", - "got": "^11.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "^4.6.2" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/webidl-conversions": { "version": "4.0.2", "dev": true, @@ -53981,8 +54321,9 @@ }, "node_modules/zod": { "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -58092,21 +58433,23 @@ } }, "@applitools/core": { - "version": "4.18.0", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/@applitools/core/-/core-4.18.2.tgz", + "integrity": "sha512-loxNLlWyEdKBLTNUj4JUvDXImFxFVXZZ/NC/k5Z+LaXix3Xk5aIpCM+8Ii5Y96WBv8G7x/ZvQop7h823z3ai0Q==", "dev": true, "requires": { - "@applitools/core-base": "1.16.0", - "@applitools/dom-capture": "11.3.0", + "@applitools/core-base": "1.16.1", + "@applitools/dom-capture": "11.4.0", "@applitools/dom-snapshot": "4.11.3", - "@applitools/driver": "1.18.0", - "@applitools/ec-client": "1.9.3", + "@applitools/driver": "1.19.0", + "@applitools/ec-client": "1.9.4", "@applitools/logger": "2.0.18", - "@applitools/nml-client": "1.8.9", + "@applitools/nml-client": "1.8.10", "@applitools/req": "1.7.2", - "@applitools/screenshoter": "3.8.35", + "@applitools/screenshoter": "3.8.36", "@applitools/snippets": "2.4.27", "@applitools/socket": "1.1.18", - "@applitools/spec-driver-webdriver": "1.1.11", + "@applitools/spec-driver-webdriver": "1.1.12", "@applitools/ufg-client": "1.12.3", "@applitools/utils": "1.7.4", "@types/ws": "8.5.5", @@ -58121,17 +58464,23 @@ "dependencies": { "semver": { "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true }, "ws": { "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "requires": {} } } }, "@applitools/core-base": { - "version": "1.16.0", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@applitools/core-base/-/core-base-1.16.1.tgz", + "integrity": "sha512-T4/BCba4b77lJRh85Ir9Gwc2cKKwzLAdrPOWbzwx2euhl7ZPUdd4U4ncQpv9uKTYFwz5zu3v5TCeUxrRpRtXqg==", "dev": true, "requires": { "@applitools/image": "1.1.13", @@ -58144,6 +58493,8 @@ }, "@applitools/css-tree": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@applitools/css-tree/-/css-tree-1.1.4.tgz", + "integrity": "sha512-rH3aq/dkTweEUgS/MKuthD79CZDqpQVJlqmxqVxLZVAzbeFxYdTG/gnfG0zj6YJ025jzcPH2ktdW16Rl3QLutg==", "dev": true, "requires": { "mdn-data": "2.1.0", @@ -58152,12 +58503,16 @@ "dependencies": { "source-map-js": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", + "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==", "dev": true } } }, "@applitools/dom-capture": { - "version": "11.3.0", + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@applitools/dom-capture/-/dom-capture-11.4.0.tgz", + "integrity": "sha512-8E5rjsuivGWx1TtZsjhwo32gF02dzwqvHf8NaN2fK+DTyomUvrh4QRD0ufUlKNeXIJhlVVgzjOkdfKjDj5pT/A==", "dev": true, "requires": { "@applitools/dom-shared": "1.0.15", @@ -58166,10 +58521,14 @@ }, "@applitools/dom-shared": { "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@applitools/dom-shared/-/dom-shared-1.0.15.tgz", + "integrity": "sha512-XN77SPfzXriU1x6gTcublSe0yUJHxlYwHesOnWQov2dMVfHx7y3qp0yrjdVC7LO2bDIJIzDlPJRhfg2otlbxig==", "dev": true }, "@applitools/dom-snapshot": { "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@applitools/dom-snapshot/-/dom-snapshot-4.11.3.tgz", + "integrity": "sha512-jdEWSbEOmD9LbzashTQ/YzYDdIKrhSBwNqNTIk8qjV8YtbQfZ+NtgCtW7nOsbknAMk95CfYEUV3R1rxCXs1XfA==", "dev": true, "requires": { "@applitools/css-tree": "1.1.4", @@ -58179,7 +58538,9 @@ } }, "@applitools/driver": { - "version": "1.18.0", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@applitools/driver/-/driver-1.19.0.tgz", + "integrity": "sha512-fXNvT08/uR87Wi2nNURT9YXJYV/2ZG6DnKutk3jxsp29uNJXaHfruMXoA0p6guAWzo9gw592K0GKLTn1BB/3YA==", "dev": true, "requires": { "@applitools/logger": "2.0.18", @@ -58190,21 +58551,25 @@ "dependencies": { "semver": { "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true } } }, "@applitools/ec-client": { - "version": "1.9.3", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@applitools/ec-client/-/ec-client-1.9.4.tgz", + "integrity": "sha512-PFuvt/XrJxzoy/fXeLTq+bE5+0mitV0whi4MUWZAnESIvHj3k3+oUUTZxPmRQEiR1zzxGvN7ar3sMQfiW+houA==", "dev": true, "requires": { - "@applitools/core-base": "1.16.0", - "@applitools/driver": "1.18.0", + "@applitools/core-base": "1.16.1", + "@applitools/driver": "1.19.0", "@applitools/logger": "2.0.18", "@applitools/req": "1.7.2", "@applitools/socket": "1.1.18", - "@applitools/spec-driver-webdriver": "1.1.11", - "@applitools/tunnel-client": "1.5.7", + "@applitools/spec-driver-webdriver": "1.1.12", + "@applitools/tunnel-client": "1.5.8", "@applitools/utils": "1.7.4", "abort-controller": "3.0.0", "webdriver": "7.31.1", @@ -58213,10 +58578,14 @@ }, "@applitools/eg-frpc": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@applitools/eg-frpc/-/eg-frpc-1.0.5.tgz", + "integrity": "sha512-9qUNiCK3R3VKxIAaLr5HO5QnUx6TioLFkJ2JcpU1ZqefApt1X2bdfS7eA4TGDXDWv/a0OIl2Lddzuo5/h3vbTw==", "dev": true }, "@applitools/eg-socks5-proxy-server": { "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@applitools/eg-socks5-proxy-server/-/eg-socks5-proxy-server-0.5.6.tgz", + "integrity": "sha512-SjjDBFeiKspX3nHKOoSQ+l4JUiJK3xJiWAEaR8b+GuMvnGFLnrvAECHhuXXG00+LwBJM8WKmfxEe17nvZe+nhg==", "dev": true, "requires": { "binary": "^0.3.0", @@ -58224,7 +58593,9 @@ } }, "@applitools/execution-grid-tunnel": { - "version": "3.0.5", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@applitools/execution-grid-tunnel/-/execution-grid-tunnel-3.0.8.tgz", + "integrity": "sha512-4S6NcpxELH4NXketD3g6VUhWDUCuwAm4F1sCZdZLpPWOSMu5QwQDYUoe6/4t5KuktTQ4K7N90NmTzQrxiFtDKA==", "dev": true, "requires": { "@applitools/eg-frpc": "1.0.5", @@ -58232,7 +58603,7 @@ "@applitools/logger": "^1.0.12", "dotenv": "^16.0.0", "encoding": "^0.1.13", - "fastify": "^3.24.1", + "fastify": "^4.28.0", "fastify-plugin": "^3.0.1", "find-process": "^1.4.7", "ini": "^3.0.0", @@ -58245,6 +58616,8 @@ "dependencies": { "@applitools/logger": { "version": "1.1.53", + "resolved": "https://registry.npmjs.org/@applitools/logger/-/logger-1.1.53.tgz", + "integrity": "sha512-4mlzYxc0MgM3WIxEwKqIjn9W7G7kMtQc2bFRxozViKOXypTfr72j8iODs88wcetP0GsXtplhZQ5/6aZN5WY9ug==", "dev": true, "requires": { "@applitools/utils": "1.3.36", @@ -58254,10 +58627,14 @@ }, "@applitools/utils": { "version": "1.3.36", + "resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.3.36.tgz", + "integrity": "sha512-eROEssh7wIW+V87PvLiHI2hUPxqoBxXFMRx3+z5qOZqXUPSR1Uz7EMFwxZcDDR7T6C3O3UDckB2aVB5fJAg5JA==", "dev": true }, "debug": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -58265,28 +58642,36 @@ }, "ini": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", + "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", "dev": true }, "ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "uuid": { "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true } } }, "@applitools/eyes-storybook": { - "version": "3.50.7", + "version": "3.50.9", + "resolved": "https://registry.npmjs.org/@applitools/eyes-storybook/-/eyes-storybook-3.50.9.tgz", + "integrity": "sha512-Zxp6cbLExsFkcoz0h1cAhJR5Ye8pXhnvBspwuaPxL437Lt1dowlCLlPkZx5LWSB9LD3u0RVdXhuE61ONPHE02A==", "dev": true, "requires": { - "@applitools/core": "4.18.0", - "@applitools/driver": "1.18.0", + "@applitools/core": "4.18.2", + "@applitools/driver": "1.19.0", "@applitools/functional-commons": "1.6.0", "@applitools/logger": "2.0.18", "@applitools/monitoring-commons": "1.0.19", - "@applitools/spec-driver-puppeteer": "1.4.11", + "@applitools/spec-driver-puppeteer": "1.4.12", "@applitools/ufg-client": "1.12.3", "@applitools/utils": "1.7.4", "boxen": "4.2.0", @@ -58444,10 +58829,14 @@ }, "@applitools/functional-commons": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@applitools/functional-commons/-/functional-commons-1.6.0.tgz", + "integrity": "sha512-fwiF0CbeYHDEOTD/NKaFgaI8LvRcGYG2GaJJiRwcedKko16sQ8F3TK5wXfj2Ytjf+8gjwHwsEEX550z3yvDWxA==", "dev": true }, "@applitools/image": { "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@applitools/image/-/image-1.1.13.tgz", + "integrity": "sha512-oeSnsTJxhD6juNlWufeWsiWV9dbS0a3OL75/r/Bo2yauAi6AsRMDeh+McXJfYlf1NVZbrVG0+vNXn52mDVEIyw==", "dev": true, "requires": { "@applitools/utils": "1.7.4", @@ -58459,6 +58848,8 @@ }, "@applitools/logger": { "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@applitools/logger/-/logger-2.0.18.tgz", + "integrity": "sha512-d54OTreCXE+G9qUxiPDHHBzwof3EnXPrADdZ7ToB9AoI+kOgs/v6wjMx0ghAoXyyOiLvlvJnmdHSyJssRdv5GA==", "dev": true, "requires": { "@applitools/utils": "1.7.4", @@ -58468,6 +58859,8 @@ "dependencies": { "debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -58475,6 +58868,8 @@ }, "ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -58500,7 +58895,9 @@ } }, "@applitools/nml-client": { - "version": "1.8.9", + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/@applitools/nml-client/-/nml-client-1.8.10.tgz", + "integrity": "sha512-avoZnD39XrWJg5x7PiFv+58YEDLbWPRIb+dHrH9LVD1HcQC8tmht2KfVLnTJLJtJgRQojqZh5H8rmplfT46t8w==", "dev": true, "requires": { "@applitools/logger": "2.0.18", @@ -58510,6 +58907,8 @@ }, "@applitools/req": { "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@applitools/req/-/req-1.7.2.tgz", + "integrity": "sha512-L0tjPFGEJFAEGaifqtmtCghjkG7M0wnEwfzbHi6O+ThtTCbg4JSDRTaNvA+PLXQoS0mFvajG40/t5a4EgAG7QQ==", "dev": true, "requires": { "@applitools/utils": "1.7.4", @@ -58521,10 +58920,14 @@ "dependencies": { "data-uri-to-buffer": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true }, "node-fetch": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", + "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", "dev": true, "requires": { "data-uri-to-buffer": "^4.0.0", @@ -58535,7 +58938,9 @@ } }, "@applitools/screenshoter": { - "version": "3.8.35", + "version": "3.8.36", + "resolved": "https://registry.npmjs.org/@applitools/screenshoter/-/screenshoter-3.8.36.tgz", + "integrity": "sha512-bzl+fs3c4L6J2t/PELxmoMGc40ZvjaExD0PMM6GvbNp3uPbDtGS348DC1ZYsSl481OxTae/uiO/iVOQP4bNZCQ==", "dev": true, "requires": { "@applitools/image": "1.1.13", @@ -58546,10 +58951,14 @@ }, "@applitools/snippets": { "version": "2.4.27", + "resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.4.27.tgz", + "integrity": "sha512-n6ckwbXWyJ+/DoV1T6bRiGXITgTgjayV0j4AzHiBx+HF3JdzygxIkWtn7yl1dJfzeqEGyrtBK6Sq1tTG2GoQcA==", "dev": true }, "@applitools/socket": { "version": "1.1.18", + "resolved": "https://registry.npmjs.org/@applitools/socket/-/socket-1.1.18.tgz", + "integrity": "sha512-EMI/MMfVH38ucuZhFWOTUR8cPvuoP9b+xi5yBJF8uLlJjxQEmGnvm+Pm3s9o3mfxQzDRddYGtpIo3TTZhMVZdQ==", "dev": true, "requires": { "@applitools/logger": "2.0.18", @@ -58557,28 +58966,34 @@ } }, "@applitools/spec-driver-puppeteer": { - "version": "1.4.11", + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/@applitools/spec-driver-puppeteer/-/spec-driver-puppeteer-1.4.12.tgz", + "integrity": "sha512-ap0H3ooVjkpGXlsjQSNJKV8uZLyTyIbEL/63snts1b3W+7wu3q884j1MI0bCW/ZOHotYeeAoqkKQ9exdDIowjw==", "dev": true, "requires": { - "@applitools/driver": "1.18.0", + "@applitools/driver": "1.19.0", "@applitools/utils": "1.7.4" } }, "@applitools/spec-driver-webdriver": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@applitools/spec-driver-webdriver/-/spec-driver-webdriver-1.1.12.tgz", + "integrity": "sha512-r6PobChadcc3couBtnf3pTunL7Vi00cNcg2l1rTr0ApSEfJ1m1DdTcX8bgXU1jDzJ2QhCn7OoqsziTajQdWmoA==", "dev": true, "requires": { - "@applitools/driver": "1.18.0", + "@applitools/driver": "1.19.0", "@applitools/utils": "1.7.4", "http-proxy-agent": "5.0.0", "https-proxy-agent": "5.0.1" } }, "@applitools/tunnel-client": { - "version": "1.5.7", + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@applitools/tunnel-client/-/tunnel-client-1.5.8.tgz", + "integrity": "sha512-SJByl2/I0NftENw5NvW+nHN+Vq64b0aeTsdCTYKhDhJBWqPEkGYwRR5ziYpk8MWYsL2hWcPUfg/S/hS+M3zmDg==", "dev": true, "requires": { - "@applitools/execution-grid-tunnel": "3.0.5", + "@applitools/execution-grid-tunnel": "3.0.8", "@applitools/logger": "2.0.18", "@applitools/req": "1.7.2", "@applitools/socket": "1.1.18", @@ -58589,6 +59004,8 @@ }, "@applitools/ufg-client": { "version": "1.12.3", + "resolved": "https://registry.npmjs.org/@applitools/ufg-client/-/ufg-client-1.12.3.tgz", + "integrity": "sha512-bSxLqxzAuc+ldum/nGoiM/iCcf97uku3bABxB90ilzUYT1DOu9vEGmaPxxGLDc+GRRVYlOYGNdIJF+DQP4dFTg==", "dev": true, "requires": { "@applitools/css-tree": "1.1.4", @@ -58603,6 +59020,8 @@ }, "@applitools/utils": { "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.7.4.tgz", + "integrity": "sha512-qgJqx2yjlJBf79YyFehf1nSp4AXOdzJn3POQyg8CMWV0YH6HsjAfJjYaNrbXFcGYCSpPEJGhGehxC7GVKHX3YA==", "dev": true }, "@aw-web-design/x-default-browser": { @@ -61322,16 +61741,74 @@ "dev": true }, "@fastify/ajv-compiler": { - "version": "1.1.0", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz", + "integrity": "sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==", "dev": true, "requires": { - "ajv": "^6.12.6" + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "fast-uri": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "dependencies": { + "fast-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", + "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "dev": true + } + } + }, + "fast-uri": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", + "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } } }, "@fastify/error": { - "version": "2.0.0", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.4.1.tgz", + "integrity": "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==", "dev": true }, + "@fastify/fast-json-stringify-compiler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", + "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", + "dev": true, + "requires": { + "fast-json-stringify": "^5.7.0" + } + }, + "@fastify/merge-json-schemas": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", + "integrity": "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, "@fontsource/fira-code": { "version": "5.0.18" }, @@ -63833,6 +64310,8 @@ }, "@puppeteer/browsers": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", + "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", "dev": true, "requires": { "debug": "^4.3.5", @@ -63846,18 +64325,24 @@ }, "dependencies": { "debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "semver": { "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true } } @@ -64255,6 +64740,8 @@ }, "@sindresorhus/is": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true }, "@sindresorhus/merge-streams": { @@ -68596,6 +69083,8 @@ }, "@szmarczak/http-timer": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, "requires": { "defer-to-connect": "^2.0.0" @@ -68707,6 +69196,8 @@ }, "@tootallnate/quickjs-emscripten": { "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", "dev": true }, "@tsconfig/node10": { @@ -68880,6 +69371,8 @@ }, "@types/cacheable-request": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dev": true, "requires": { "@types/http-cache-semantics": "*", @@ -69076,6 +69569,8 @@ }, "@types/glob": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", "dev": true, "requires": { "@types/minimatch": "^5.1.2", @@ -69084,6 +69579,8 @@ "dependencies": { "@types/minimatch": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true } } @@ -69231,6 +69728,8 @@ }, "@types/keyv": { "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dev": true, "requires": { "@types/node": "*" @@ -69464,6 +69963,8 @@ }, "@types/responselike": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, "requires": { "@types/node": "*" @@ -70465,6 +70966,8 @@ }, "@wdio/config": { "version": "7.31.1", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.31.1.tgz", + "integrity": "sha512-WAfswbCatwiaDVqy6kfF/5T8/WS/US/SRhBGUFrfBuGMIe+RRoHgy7jURFWSvUIE7CNHj8yvs46fLUcxhXjzcQ==", "dev": true, "requires": { "@types/glob": "^8.1.0", @@ -70475,23 +70978,10 @@ "glob": "^8.0.3" }, "dependencies": { - "@types/node": { - "version": "18.19.42", - "dev": true, - "requires": { - "undici-types": "~5.26.4" - } - }, - "@wdio/types": { - "version": "7.30.2", - "dev": true, - "requires": { - "@types/node": "^18.0.0", - "got": "^11.8.1" - } - }, "brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { "balanced-match": "^1.0.0" @@ -70499,10 +70989,14 @@ }, "deepmerge": { "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 }, "glob": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -70514,6 +71008,8 @@ }, "minimatch": { "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -70523,6 +71019,8 @@ }, "@wdio/logger": { "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.26.0.tgz", + "integrity": "sha512-kQj9s5JudAG9qB+zAAcYGPHVfATl2oqKgqj47yjehOQ1zzG33xmtL1ArFbQKWhDG32y1A8sN6b0pIqBEIwgg8Q==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -70533,34 +71031,42 @@ }, "@wdio/protocols": { "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.27.0.tgz", + "integrity": "sha512-hT/U22R5i3HhwPjkaKAG0yd59eaOaZB0eibRj2+esCImkb5Y6rg8FirrlYRxIGFVBl0+xZV0jKHzR5+o097nvg==", "dev": true }, - "@wdio/utils": { + "@wdio/types": { "version": "7.30.2", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", + "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, "requires": { - "@wdio/logger": "7.26.0", - "@wdio/types": "7.30.2", - "p-iteration": "^1.1.8" + "@types/node": "^18.0.0", + "got": "^11.8.1" }, "dependencies": { "@types/node": { - "version": "18.19.42", + "version": "18.19.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.55.tgz", + "integrity": "sha512-zzw5Vw52205Zr/nmErSEkN5FLqXPuKX/k5d1D7RKHATGqU7y6YfX9QxZraUzUrFGqH6XzOzG196BC35ltJC4Cw==", "dev": true, "requires": { "undici-types": "~5.26.4" } - }, - "@wdio/types": { - "version": "7.30.2", - "dev": true, - "requires": { - "@types/node": "^18.0.0", - "got": "^11.8.1" - } } } }, + "@wdio/utils": { + "version": "7.30.2", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.30.2.tgz", + "integrity": "sha512-np7I+smszFUennbQKdzbMN/zUL3s3EZq9pCCUcTRjjs9TE4tnn0wfmGdoz2o7REYu6kn9NfFFJyVIM2VtBbKEA==", + "dev": true, + "requires": { + "@wdio/logger": "7.26.0", + "@wdio/types": "7.30.2", + "p-iteration": "^1.1.8" + } + }, "@webassemblyjs/ast": { "version": "1.12.1", "devOptional": true, @@ -70696,6 +71202,8 @@ }, "@xmldom/xmldom": { "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", "dev": true }, "@xtuc/ieee754": { @@ -70876,6 +71384,8 @@ }, "abstract-logging": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", "dev": true }, "accepts": { @@ -71495,7 +72005,8 @@ }, "archy": { "version": "1.0.0", - "dev": true + "dev": true, + "peer": true }, "arg": { "version": "4.1.3", @@ -71755,32 +72266,21 @@ }, "atomic-sleep": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", "dev": true }, "available-typed-arrays": { "version": "1.0.6" }, "avvio": { - "version": "7.2.5", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.4.0.tgz", + "integrity": "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==", "dev": true, "requires": { - "archy": "^1.0.0", - "debug": "^4.0.0", - "fastq": "^1.6.1", - "queue-microtask": "^1.1.2" - }, - "dependencies": { - "debug": { - "version": "4.3.6", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "dev": true - } + "@fastify/error": "^3.3.0", + "fastq": "^1.17.1" } }, "aws-sign2": { @@ -72165,7 +72665,9 @@ "optional": true }, "bare-fs": { - "version": "2.3.1", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", "dev": true, "optional": true, "requires": { @@ -72175,12 +72677,16 @@ } }, "bare-os": { - "version": "2.4.0", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", "dev": true, "optional": true }, "bare-path": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", "dev": true, "optional": true, "requires": { @@ -72188,11 +72694,14 @@ } }, "bare-stream": { - "version": "2.1.3", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz", + "integrity": "sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==", "dev": true, "optional": true, "requires": { - "streamx": "^2.18.0" + "b4a": "^1.6.6", + "streamx": "^2.20.0" } }, "base": { @@ -72252,6 +72761,8 @@ }, "basic-ftp": { "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true }, "batch": { @@ -72336,6 +72847,8 @@ }, "binary": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", "dev": true, "requires": { "buffers": "~0.1.1", @@ -72392,6 +72905,8 @@ }, "bmpimagejs": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bmpimagejs/-/bmpimagejs-1.0.4.tgz", + "integrity": "sha512-21oKU7kbRt2OgOOj7rdiNr/yznDNUQ585plxR00rsmECcZr+6O1oCwB8OIoSHk/bDhbG8mFXIdeQuCPHgZ6QBw==", "dev": true }, "body-parser": { @@ -72592,6 +73107,8 @@ }, "buffers": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", "dev": true }, "bundle-name": { @@ -72755,10 +73272,14 @@ }, "cacheable-lookup": { "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "dev": true }, "cacheable-request": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, "requires": { "clone-response": "^1.0.2", @@ -72772,6 +73293,8 @@ "dependencies": { "get-stream": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -72892,6 +73415,8 @@ }, "chainsaw": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", "dev": true, "requires": { "traverse": ">=0.3.0 <0.4" @@ -72899,6 +73424,8 @@ "dependencies": { "traverse": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", "dev": true } } @@ -73052,6 +73579,8 @@ }, "chromium-bidi": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", + "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", "dev": true, "requires": { "mitt": "3.0.1", @@ -73061,6 +73590,8 @@ "dependencies": { "mitt": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "dev": true } } @@ -73215,6 +73746,8 @@ }, "clone-response": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "dev": true, "requires": { "mimic-response": "^1.0.0" @@ -73668,7 +74201,9 @@ } }, "cookie": { - "version": "0.5.0", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true }, "cookie-signature": { @@ -74571,6 +75106,8 @@ }, "data-uri-to-buffer": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "dev": true }, "data-urls": { @@ -74969,6 +75506,8 @@ }, "degenerator": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, "requires": { "ast-types": "^0.13.4", @@ -74978,6 +75517,8 @@ "dependencies": { "ast-types": { "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, "requires": { "tslib": "^2.0.1" @@ -74985,6 +75526,8 @@ }, "escodegen": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, "requires": { "esprima": "^4.0.1", @@ -74995,19 +75538,27 @@ }, "esprima": { "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 }, "estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "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, "optional": true }, "tslib": { - "version": "2.6.3", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true } } @@ -75145,6 +75696,8 @@ }, "devtools-protocol": { "version": "0.0.1312386", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz", + "integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==", "dev": true }, "diff": { @@ -76895,9 +77448,9 @@ } }, "express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, "requires": { "accepts": "~1.3.8", @@ -76905,7 +77458,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -76938,7 +77491,9 @@ "dev": true }, "cookie": { - "version": "0.6.0", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true }, "depd": { @@ -77132,10 +77687,14 @@ }, "fast-content-type-parse": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", + "integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==", "dev": true }, "fast-decode-uri-component": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", "dev": true }, "fast-deep-equal": { @@ -77207,17 +77766,59 @@ "devOptional": true }, "fast-json-stringify": { - "version": "2.7.13", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", + "integrity": "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==", "dev": true, "requires": { - "ajv": "^6.11.0", - "deepmerge": "^4.2.2", - "rfdc": "^1.2.0", - "string-similarity": "^4.0.1" + "@fastify/merge-json-schemas": "^0.1.0", + "ajv": "^8.10.0", + "ajv-formats": "^3.0.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^2.1.0", + "json-schema-ref-resolver": "^1.0.1", + "rfdc": "^1.2.0" }, "dependencies": { - "deepmerge": { - "version": "4.3.1", + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "dependencies": { + "fast-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", + "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "dev": true + } + } + }, + "ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "fast-uri": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", + "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true } } @@ -77225,8 +77826,19 @@ "fast-levenshtein": { "version": "2.0.6" }, + "fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "dev": true, + "requires": { + "fast-decode-uri-component": "^1.0.1" + } + }, "fast-redact": { "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", "dev": true }, "fast-safe-stringify": { @@ -77248,39 +77860,47 @@ "dev": true }, "fastify": { - "version": "3.29.5", - "dev": true, - "requires": { - "@fastify/ajv-compiler": "^1.0.0", - "@fastify/error": "^2.0.0", - "abstract-logging": "^2.0.0", - "avvio": "^7.1.2", - "fast-content-type-parse": "^1.0.0", - "fast-json-stringify": "^2.5.2", - "find-my-way": "^4.5.0", - "flatstr": "^1.0.12", - "light-my-request": "^4.2.0", - "pino": "^6.13.0", - "process-warning": "^1.0.0", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.28.1.tgz", + "integrity": "sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==", + "dev": true, + "requires": { + "@fastify/ajv-compiler": "^3.5.0", + "@fastify/error": "^3.4.0", + "@fastify/fast-json-stringify-compiler": "^4.3.0", + "abstract-logging": "^2.0.1", + "avvio": "^8.3.0", + "fast-content-type-parse": "^1.1.0", + "fast-json-stringify": "^5.8.0", + "find-my-way": "^8.0.0", + "light-my-request": "^5.11.0", + "pino": "^9.0.0", + "process-warning": "^3.0.0", "proxy-addr": "^2.0.7", - "rfdc": "^1.1.4", - "secure-json-parse": "^2.0.0", - "semver": "^7.3.2", - "tiny-lru": "^8.0.1" + "rfdc": "^1.3.0", + "secure-json-parse": "^2.7.0", + "semver": "^7.5.4", + "toad-cache": "^3.3.0" }, "dependencies": { "semver": { "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true } } }, "fastify-plugin": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-3.0.1.tgz", + "integrity": "sha512-qKcDXmuZadJqdTm6vlCqioEbyewF60b/0LOFCcYN1B6BIZGlYJumWWOYs70SFYLDAH4YqdE1cxH/RKMG7rFxgA==", "dev": true }, "fastq": { - "version": "1.8.0", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "requires": { "reusify": "^1.0.4" } @@ -77480,17 +78100,20 @@ } }, "find-my-way": { - "version": "4.5.1", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.2.tgz", + "integrity": "sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==", "dev": true, "requires": { - "fast-decode-uri-component": "^1.0.1", "fast-deep-equal": "^3.1.3", - "safe-regex2": "^2.0.0", - "semver-store": "^0.3.0" + "fast-querystring": "^1.0.0", + "safe-regex2": "^3.1.0" } }, "find-process": { "version": "1.4.7", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.7.tgz", + "integrity": "sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -77500,17 +78123,23 @@ "dependencies": { "commander": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true }, "debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } @@ -77553,10 +78182,6 @@ } } }, - "flatstr": { - "version": "1.0.12", - "dev": true - }, "flatted": { "version": "3.1.0", "dev": true @@ -78091,6 +78716,8 @@ }, "get-uri": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dev": true, "requires": { "basic-ftp": "^5.0.2", @@ -78100,14 +78727,18 @@ }, "dependencies": { "debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } @@ -78474,6 +79105,8 @@ }, "got": { "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, "requires": { "@sindresorhus/is": "^4.0.0", @@ -79223,6 +79856,8 @@ }, "http2-wrapper": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "dev": true, "requires": { "quick-lru": "^5.1.1", @@ -79231,6 +79866,8 @@ "dependencies": { "quick-lru": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true } } @@ -79745,6 +80382,8 @@ }, "is-localhost-ip": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-localhost-ip/-/is-localhost-ip-2.0.0.tgz", + "integrity": "sha512-vlgs2cSgMOfnKU8c1ewgKPyum9rVrjjLLW2HBdL5i0iAJjOs8NY55ZBd/hqUTaYR0EO9CKZd3hVSC2HlIbygTQ==", "dev": true }, "is-map": { @@ -81662,6 +82301,8 @@ }, "jpeg-js": { "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", "dev": true }, "jquery": { @@ -81989,6 +82630,15 @@ "lodash": "^4.17.20" } }, + "json-schema-ref-resolver": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", + "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, "json-schema-traverse": { "version": "0.4.1", "devOptional": true @@ -82125,6 +82775,8 @@ }, "ky": { "version": "0.30.0", + "resolved": "https://registry.npmjs.org/ky/-/ky-0.30.0.tgz", + "integrity": "sha512-X/u76z4JtDVq10u1JA5UQfatPxgPaVDMYTrgHyiTpGN2z4TMEJkIHsoSBBSg9SWZEIXTKsi9kHgiQ9o3Y/4yog==", "dev": true }, "language-subtag-registry": { @@ -82735,29 +83387,14 @@ } }, "light-my-request": { - "version": "4.12.0", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.14.0.tgz", + "integrity": "sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==", "dev": true, "requires": { - "ajv": "^8.1.0", - "cookie": "^0.5.0", - "process-warning": "^1.0.0", + "cookie": "^0.7.0", + "process-warning": "^3.0.0", "set-cookie-parser": "^2.4.1" - }, - "dependencies": { - "ajv": { - "version": "8.17.1", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "dev": true - } } }, "lilconfig": { @@ -82947,11 +83584,15 @@ } }, "loglevel": { - "version": "1.9.1", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", "dev": true }, "loglevel-plugin-prefix": { "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", "dev": true }, "long": { @@ -82979,6 +83620,8 @@ }, "lowercase-keys": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true }, "lowlight": { @@ -84931,6 +85574,8 @@ }, "mdn-data": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.1.0.tgz", + "integrity": "sha512-dbAWH6A+2NGuVJlQFrTKHJc07Vqn5frnhyTOGz+7BsK7V2hHdoBcwoiyV3QVhLHYpM/zqe2OSUn5ZWbVXLBB8A==", "dev": true }, "media-typer": { @@ -85770,6 +86415,8 @@ }, "mimic-response": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, "min-document": { @@ -86170,6 +86817,8 @@ }, "netmask": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true }, "nice-try": { @@ -86215,6 +86864,8 @@ }, "node-cleanup": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", + "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", "dev": true }, "node-dir": { @@ -86536,6 +87187,8 @@ }, "normalize-url": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true }, "npm-bundled": { @@ -87253,11 +87906,19 @@ }, "omggif": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", "dev": true }, "omit.js": { "version": "2.0.2" }, + "on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "dev": true + }, "on-finished": { "version": "2.4.1", "dev": true, @@ -87377,6 +88038,8 @@ }, "p-cancelable": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "dev": true }, "p-finally": { @@ -87385,6 +88048,8 @@ }, "p-iteration": { "version": "1.1.8", + "resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz", + "integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==", "dev": true }, "p-limit": { @@ -87468,6 +88133,8 @@ }, "pac-proxy-agent": { "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", "dev": true, "requires": { "@tootallnate/quickjs-emscripten": "^0.23.0", @@ -87482,20 +88149,26 @@ "dependencies": { "agent-base": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" } }, "debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "http-proxy-agent": { "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, "requires": { "agent-base": "^7.1.0", @@ -87504,6 +88177,8 @@ }, "https-proxy-agent": { "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "requires": { "agent-base": "^7.0.2", @@ -87511,13 +88186,17 @@ } }, "ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } }, "pac-resolver": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, "requires": { "degenerator": "^5.0.0", @@ -87670,6 +88349,8 @@ }, "pako": { "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, "param-case": { @@ -87934,20 +88615,92 @@ } }, "pino": { - "version": "6.14.0", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.4.0.tgz", + "integrity": "sha512-nbkQb5+9YPhQRz/BeQmrWpEknAaqjpAqRK8NwJpmrX/JHu7JuZC5G1CeAwJDJfGes4h+YihC6in3Q2nGb+Y09w==", "dev": true, "requires": { - "fast-redact": "^3.0.0", - "fast-safe-stringify": "^2.0.8", - "flatstr": "^1.0.12", - "pino-std-serializers": "^3.1.0", - "process-warning": "^1.0.0", + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^4.0.0", "quick-format-unescaped": "^4.0.3", - "sonic-boom": "^1.0.2" + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "dependencies": { + "process-warning": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.0.tgz", + "integrity": "sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==", + "dev": true + } + } + }, + "pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "dev": true, + "requires": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } } }, "pino-std-serializers": { - "version": "3.2.0", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", "dev": true }, "pirates": { @@ -88011,6 +88764,8 @@ }, "png-async": { "version": "0.9.4", + "resolved": "https://registry.npmjs.org/png-async/-/png-async-0.9.4.tgz", + "integrity": "sha512-B//AXX9TkneKfgtOpT1mdUnnhk2BImGD+a98vImsMU8uo1dBeHyW/kM2erWZ/CsYteTPU/xKG+t6T62heHkC3A==", "dev": true }, "po2json": { @@ -88393,7 +89148,9 @@ } }, "process-warning": { - "version": "1.0.0", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", "dev": true }, "proggy": { @@ -88402,6 +89159,8 @@ }, "progress": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "promise": { @@ -88512,6 +89271,8 @@ }, "proxy-agent": { "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", "dev": true, "requires": { "agent-base": "^7.0.2", @@ -88526,20 +89287,26 @@ "dependencies": { "agent-base": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" } }, "debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "http-proxy-agent": { "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, "requires": { "agent-base": "^7.1.0", @@ -88548,6 +89315,8 @@ }, "https-proxy-agent": { "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "requires": { "agent-base": "^7.0.2", @@ -88556,14 +89325,20 @@ }, "lru-cache": { "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true }, "ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "proxy-from-env": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true } } @@ -88613,6 +89388,8 @@ }, "puppeteer": { "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.15.0.tgz", + "integrity": "sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==", "dev": true, "requires": { "@puppeteer/browsers": "2.3.0", @@ -88623,10 +89400,14 @@ "dependencies": { "argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "cosmiconfig": { "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "requires": { "env-paths": "^2.2.1", @@ -88637,6 +89418,8 @@ }, "js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { "argparse": "^2.0.1" @@ -88644,6 +89427,8 @@ }, "parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -88656,6 +89441,8 @@ }, "puppeteer-core": { "version": "22.15.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", + "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", "dev": true, "requires": { "@puppeteer/browsers": "2.3.0", @@ -88666,18 +89453,24 @@ }, "dependencies": { "debug": { - "version": "4.3.6", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "ms": { - "version": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "ws": { "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "requires": {} } @@ -88722,6 +89515,8 @@ }, "quick-format-unescaped": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", "dev": true }, "quick-lru": { @@ -89991,6 +90786,12 @@ } } }, + "real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true + }, "realpath-native": { "version": "1.1.0", "dev": true, @@ -90990,6 +91791,8 @@ }, "responselike": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, "requires": { "lowercase-keys": "^2.0.0" @@ -91016,6 +91819,8 @@ }, "rfdc": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, "rimraf": { @@ -91195,18 +92000,28 @@ } }, "safe-regex2": { - "version": "2.0.0", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz", + "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==", "dev": true, "requires": { - "ret": "~0.2.0" + "ret": "~0.4.0" }, "dependencies": { "ret": { - "version": "0.2.2", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz", + "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==", "dev": true } } }, + "safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "dev": true + }, "safer-buffer": { "version": "2.1.2" }, @@ -91253,6 +92068,8 @@ }, "secure-json-parse": { "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", "dev": true }, "seedrandom": { @@ -91273,10 +92090,6 @@ "version": "5.7.2", "dev": true }, - "semver-store": { - "version": "0.3.0", - "dev": true - }, "send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -91392,7 +92205,9 @@ "dev": true }, "set-cookie-parser": { - "version": "2.6.0", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", + "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==", "dev": true }, "set-function-length": { @@ -91787,11 +92602,12 @@ } }, "sonic-boom": { - "version": "1.4.1", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.1.0.tgz", + "integrity": "sha512-NGipjjRicyJJ03rPiZCJYjwlsuP2d1/5QUviozRXC7S3WdVWNK5e3Ojieb9CCyfhq2UC+3+SRd9nG3I2lPRvUw==", "dev": true, "requires": { - "atomic-sleep": "^1.0.0", - "flatstr": "^1.0.12" + "atomic-sleep": "^1.0.0" } }, "sort-keys": { @@ -92270,7 +93086,9 @@ "version": "1.0.3" }, "streamx": { - "version": "2.18.0", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", "requires": { "bare-events": "^2.2.0", "fast-fifo": "^1.3.2", @@ -92301,10 +93119,6 @@ "strip-ansi": "^6.0.0" } }, - "string-similarity": { - "version": "4.0.4", - "dev": true - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -92589,6 +93403,8 @@ }, "tar-fs": { "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, "requires": { "bare-fs": "^2.1.1", @@ -92599,6 +93415,8 @@ "dependencies": { "tar-stream": { "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, "requires": { "b4a": "^1.6.4", @@ -92632,6 +93450,8 @@ }, "teen_process": { "version": "1.16.0", + "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-1.16.0.tgz", + "integrity": "sha512-RnW7HHZD1XuhSTzD3djYOdIl1adE3oNEprE3HOFFxWs5m4FZsqYRhKJ4mDU2udtNGMLUS7jV7l8vVRLWAvmPDw==", "dev": true, "requires": { "@babel/runtime": "^7.0.0", @@ -92644,6 +93464,8 @@ "dependencies": { "which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -92838,8 +93660,19 @@ } } }, + "thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "dev": true, + "requires": { + "real-require": "^0.2.0" + } + }, "throat": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", "dev": true }, "throttle-debounce": { @@ -92875,10 +93708,6 @@ "tiny-invariant": { "version": "1.3.3" }, - "tiny-lru": { - "version": "8.0.2", - "dev": true - }, "tiny-warning": { "version": "1.0.3" }, @@ -92962,6 +93791,12 @@ "repeat-string": "^1.6.1" } }, + "toad-cache": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", + "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==", + "dev": true + }, "tocbot": { "version": "4.28.2" }, @@ -93323,6 +94158,8 @@ }, "unbzip2-stream": { "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "requires": { "buffer": "^5.2.1", @@ -93565,6 +94402,8 @@ }, "urlpattern-polyfill": { "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "dev": true }, "use": { @@ -93891,6 +94730,8 @@ }, "webdriver": { "version": "7.31.1", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.31.1.tgz", + "integrity": "sha512-nCdJLxRnYvOMFqTEX7sqQtF/hV/Jgov0Y6ICeOm1DMTlZSRRDaUsBMlEAPkEwif9uBJYdM0znv8qzfX358AGqQ==", "dev": true, "requires": { "@types/node": "^18.0.0", @@ -93905,19 +94746,13 @@ }, "dependencies": { "@types/node": { - "version": "18.19.42", + "version": "18.19.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.55.tgz", + "integrity": "sha512-zzw5Vw52205Zr/nmErSEkN5FLqXPuKX/k5d1D7RKHATGqU7y6YfX9QxZraUzUrFGqH6XzOzG196BC35ltJC4Cw==", "dev": true, "requires": { "undici-types": "~5.26.4" } - }, - "@wdio/types": { - "version": "7.30.2", - "dev": true, - "requires": { - "@types/node": "^18.0.0", - "got": "^11.8.1" - } } } }, @@ -94873,6 +95708,8 @@ }, "zod": { "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "dev": true }, "zrender": { diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 258738112ce03..736c294de0ea6 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -211,7 +211,7 @@ "yargs": "^17.7.2" }, "devDependencies": { - "@applitools/eyes-storybook": "^3.50.7", + "@applitools/eyes-storybook": "^3.50.9", "@babel/cli": "^7.22.6", "@babel/compat-data": "^7.22.6", "@babel/core": "^7.23.9", From 7132d5a86a54d31849d339ebe07b86bd8150addd Mon Sep 17 00:00:00 2001 From: Ville Brofeldt <33317356+villebro@users.noreply.github.com> Date: Tue, 15 Oct 2024 10:37:28 -0700 Subject: [PATCH 16/23] chore(number-formatter): upgrade pretty-ms to 9.1.0 (#30599) --- superset-frontend/jest.config.js | 2 +- superset-frontend/package-lock.json | 65 +++++++++--------- .../packages/superset-ui-core/package.json | 2 +- .../factories/createDurationFormatter.ts | 7 +- .../factories/createDurationFormatter.test.ts | 67 ++++++++++--------- 5 files changed, 74 insertions(+), 69 deletions(-) diff --git a/superset-frontend/jest.config.js b/superset-frontend/jest.config.js index 9caf67f166ae6..22e5db98b312d 100644 --- a/superset-frontend/jest.config.js +++ b/superset-frontend/jest.config.js @@ -56,7 +56,7 @@ module.exports = { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], snapshotSerializers: ['@emotion/jest/enzyme-serializer'], transformIgnorePatterns: [ - 'node_modules/(?!d3-(interpolate|color|time)|remark-gfm|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|@rjsf/*.|sinon|echarts|zrender|fetch-mock)', + 'node_modules/(?!d3-(interpolate|color|time)|remark-gfm|markdown-table|micromark-*.|decode-named-character-reference|character-entities|mdast-util-*.|unist-util-*.|ccount|escape-string-regexp|nanoid|@rjsf/*.|sinon|echarts|zrender|fetch-mock|pretty-ms|parse-ms)', ], globals: { __DEV__: true, diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 9c90f016f285b..e08995b929eaf 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -42976,13 +42976,6 @@ "node": ">=4" } }, - "node_modules/parse-ms": { - "version": "2.1.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/parse-node-version": { "version": "1.0.1", "dev": true, @@ -44119,19 +44112,6 @@ "node": ">= 0.8" } }, - "node_modules/pretty-ms": { - "version": "7.0.1", - "license": "MIT", - "dependencies": { - "parse-ms": "^2.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/prismjs": { "version": "1.27.0", "license": "MIT", @@ -55984,7 +55964,7 @@ "jed": "^1.1.1", "lodash": "^4.17.21", "math-expression-evaluator": "^1.3.8", - "pretty-ms": "^7.0.0", + "pretty-ms": "^9.1.0", "react-error-boundary": "^1.2.5", "react-markdown": "^8.0.7", "rehype-raw": "^7.0.0", @@ -56414,6 +56394,25 @@ "url": "https://opencollective.com/unified" } }, + "packages/superset-ui-core/node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "engines": { + "node": ">=18" + } + }, + "packages/superset-ui-core/node_modules/pretty-ms": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz", + "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, "packages/superset-ui-core/node_modules/remark-gfm": { "version": "3.0.1", "license": "MIT", @@ -66353,7 +66352,7 @@ "jest-mock-console": "^2.0.0", "lodash": "^4.17.21", "math-expression-evaluator": "^1.3.8", - "pretty-ms": "^7.0.0", + "pretty-ms": "^9.1.0", "react-error-boundary": "^1.2.5", "react-markdown": "^8.0.7", "rehype-raw": "^7.0.0", @@ -66629,6 +66628,19 @@ "uvu": "^0.5.0" } }, + "parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==" + }, + "pretty-ms": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz", + "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==", + "requires": { + "parse-ms": "^4.0.0" + } + }, "remark-gfm": { "version": "3.0.1", "requires": { @@ -88446,9 +88458,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "parse-ms": { - "version": "2.1.0" - }, "parse-node-version": { "version": "1.0.1", "dev": true @@ -89110,12 +89119,6 @@ "pretty-hrtime": { "version": "1.0.3" }, - "pretty-ms": { - "version": "7.0.1", - "requires": { - "parse-ms": "^2.1.0" - } - }, "prismjs": { "version": "1.27.0" }, diff --git a/superset-frontend/packages/superset-ui-core/package.json b/superset-frontend/packages/superset-ui-core/package.json index e532c0e87a5d0..b67dc924222f3 100644 --- a/superset-frontend/packages/superset-ui-core/package.json +++ b/superset-frontend/packages/superset-ui-core/package.json @@ -37,7 +37,7 @@ "jed": "^1.1.1", "lodash": "^4.17.21", "math-expression-evaluator": "^1.3.8", - "pretty-ms": "^7.0.0", + "pretty-ms": "^9.1.0", "react-error-boundary": "^1.2.5", "react-markdown": "^8.0.7", "rehype-raw": "^7.0.0", diff --git a/superset-frontend/packages/superset-ui-core/src/number-format/factories/createDurationFormatter.ts b/superset-frontend/packages/superset-ui-core/src/number-format/factories/createDurationFormatter.ts index 440e0b17c8541..958136d90c2a5 100644 --- a/superset-frontend/packages/superset-ui-core/src/number-format/factories/createDurationFormatter.ts +++ b/superset-frontend/packages/superset-ui-core/src/number-format/factories/createDurationFormatter.ts @@ -17,7 +17,7 @@ * under the License. */ -import prettyMsFormatter from 'pretty-ms'; +import prettyMilliseconds, { Options } from 'pretty-ms'; import NumberFormatter from '../NumberFormatter'; export default function createDurationFormatter( @@ -26,13 +26,14 @@ export default function createDurationFormatter( id?: string; label?: string; multiplier?: number; - } & prettyMsFormatter.Options = {}, + } & Options = {}, ) { const { description, id, label, multiplier = 1, ...prettyMsOptions } = config; return new NumberFormatter({ description, - formatFunc: value => prettyMsFormatter(value * multiplier, prettyMsOptions), + formatFunc: value => + prettyMilliseconds(value * multiplier, prettyMsOptions), id: id ?? 'duration_format', label: label ?? `Duration formatter`, }); diff --git a/superset-frontend/packages/superset-ui-core/test/number-format/factories/createDurationFormatter.test.ts b/superset-frontend/packages/superset-ui-core/test/number-format/factories/createDurationFormatter.test.ts index fa24948163cbb..0e7c6fff7f6ff 100644 --- a/superset-frontend/packages/superset-ui-core/test/number-format/factories/createDurationFormatter.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/number-format/factories/createDurationFormatter.test.ts @@ -19,40 +19,41 @@ import { NumberFormatter, createDurationFormatter } from '@superset-ui/core'; -describe('createDurationFormatter()', () => { - it('creates an instance of NumberFormatter', () => { - const formatter = createDurationFormatter(); - expect(formatter).toBeInstanceOf(NumberFormatter); - }); - it('format milliseconds in human readable format with default options', () => { - const formatter = createDurationFormatter(); - expect(formatter(0)).toBe('0ms'); - expect(formatter(1000)).toBe('1s'); - expect(formatter(1337)).toBe('1.3s'); - expect(formatter(10500)).toBe('10.5s'); - expect(formatter(60 * 1000)).toBe('1m'); - expect(formatter(90 * 1000)).toBe('1m 30s'); +test('creates an instance of NumberFormatter', () => { + const formatter = createDurationFormatter(); + expect(formatter).toBeInstanceOf(NumberFormatter); +}); +test('format milliseconds in human readable format with default options', () => { + const formatter = createDurationFormatter(); + expect(formatter(-1000)).toBe('-1s'); + expect(formatter(0)).toBe('0ms'); + expect(formatter(1000)).toBe('1s'); + expect(formatter(1337)).toBe('1.3s'); + expect(formatter(10500)).toBe('10.5s'); + expect(formatter(60 * 1000)).toBe('1m'); + expect(formatter(90 * 1000)).toBe('1m 30s'); +}); +test('format seconds in human readable format with default options', () => { + const formatter = createDurationFormatter({ multiplier: 1000 }); + expect(formatter(-0.5)).toBe('-500ms'); + expect(formatter(0.5)).toBe('500ms'); + expect(formatter(1)).toBe('1s'); + expect(formatter(30)).toBe('30s'); + expect(formatter(60)).toBe('1m'); + expect(formatter(90)).toBe('1m 30s'); +}); +test('format milliseconds in human readable format with additional pretty-ms options', () => { + const colonNotationFormatter = createDurationFormatter({ + colonNotation: true, }); - it('format seconds in human readable format with default options', () => { - const formatter = createDurationFormatter({ multiplier: 1000 }); - expect(formatter(0.5)).toBe('500ms'); - expect(formatter(1)).toBe('1s'); - expect(formatter(30)).toBe('30s'); - expect(formatter(60)).toBe('1m'); - expect(formatter(90)).toBe('1m 30s'); + expect(colonNotationFormatter(-10500)).toBe('-0:10.5'); + expect(colonNotationFormatter(10500)).toBe('0:10.5'); + const zeroDecimalFormatter = createDurationFormatter({ + secondsDecimalDigits: 0, }); - it('format milliseconds in human readable format with additional pretty-ms options', () => { - const colonNotationFormatter = createDurationFormatter({ - colonNotation: true, - }); - expect(colonNotationFormatter(10500)).toBe('0:10.5'); - const zeroDecimalFormatter = createDurationFormatter({ - secondsDecimalDigits: 0, - }); - expect(zeroDecimalFormatter(10500)).toBe('10s'); - const subMillisecondFormatter = createDurationFormatter({ - formatSubMilliseconds: true, - }); - expect(subMillisecondFormatter(100.40008)).toBe('100ms 400µs 80ns'); + expect(zeroDecimalFormatter(10500)).toBe('10s'); + const subMillisecondFormatter = createDurationFormatter({ + formatSubMilliseconds: true, }); + expect(subMillisecondFormatter(100.40008)).toBe('100ms 400µs 80ns'); }); From d6b2e86155184e6abe26a4c39d6841ed6130627b Mon Sep 17 00:00:00 2001 From: Yerkebulan <42295524+deathstrokedarksky@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:55:12 +0600 Subject: [PATCH 17/23] fix: Set correct amount of steps to avoid confusing logs while loading examples (#30606) --- docker/docker-init.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docker/docker-init.sh b/docker/docker-init.sh index 397bb7d9869a1..4016fd898a038 100755 --- a/docker/docker-init.sh +++ b/docker/docker-init.sh @@ -22,7 +22,11 @@ set -e # /app/docker/docker-bootstrap.sh -STEP_CNT=4 +if [ "$SUPERSET_LOAD_EXAMPLES" = "yes" ]; then + STEP_CNT=4 +else + STEP_CNT=3 +fi echo_step() { cat < Date: Tue, 15 Oct 2024 14:32:02 -0400 Subject: [PATCH 18/23] feat: use dialect when tokenizing (#30614) --- superset/sql/parse.py | 4 ++-- tests/unit_tests/sql_parse_tests.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/superset/sql/parse.py b/superset/sql/parse.py index 33ed76473facc..2c7276baba00a 100644 --- a/superset/sql/parse.py +++ b/superset/sql/parse.py @@ -276,7 +276,7 @@ def split_script( script: str, engine: str, ) -> list[SQLStatement]: - if engine in SQLGLOT_DIALECTS: + if dialect := SQLGLOT_DIALECTS.get(engine): try: return [ cls(ast.sql(), engine, ast) @@ -297,7 +297,7 @@ def split_script( remainder = script try: - tokens = sqlglot.tokenize(script) + tokens = sqlglot.tokenize(script, dialect) except sqlglot.errors.TokenError as ex: raise SupersetParseError( script, diff --git a/tests/unit_tests/sql_parse_tests.py b/tests/unit_tests/sql_parse_tests.py index 44d52c7f6e8fb..cf6eda3dda7f0 100644 --- a/tests/unit_tests/sql_parse_tests.py +++ b/tests/unit_tests/sql_parse_tests.py @@ -281,7 +281,7 @@ def test_extract_tables_illdefined() -> None: extract_tables('SELECT * FROM "tbname') assert ( str(excinfo.value) - == "You may have an error in your SQL statement. Unable to parse script" + == "You may have an error in your SQL statement. Unable to tokenize script" ) # odd edge case that works From 362948324c7718e74c0a9655332249c0e1328703 Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Wed, 16 Oct 2024 02:13:05 +0300 Subject: [PATCH 19/23] fix(Filters): Apply native & cross filters on common columns (#30438) --- docs/static/resources/openapi.json | 6 + .../superset-ui-chart-controls/src/types.ts | 1 + .../src/query/types/Dashboard.ts | 36 +++ .../test/query/types/Dashboard.test.ts | 28 ++ .../spec/fixtures/mockDashboardInfo.js | 1 + .../spec/fixtures/mockNativeFilters.ts | 1 + .../src/dashboard/actions/dashboardState.js | 13 +- .../src/dashboard/components/Dashboard.jsx | 31 ++- .../dashboard/components/Dashboard.test.jsx | 29 ++ .../OverwriteConfirmModal.test.tsx | 5 + .../dashboard/fixtures/mockNativeFilters.ts | 1 + .../util/activeAllDashboardFilters.ts | 4 + .../src/dashboard/util/crossFilters.test.ts | 4 +- .../src/dashboard/util/crossFilters.ts | 19 +- .../dashboard/util/getRelatedCharts.test.ts | 254 ++++++++++++++++++ .../src/dashboard/util/getRelatedCharts.ts | 200 ++++++++++++++ .../useFilterFocusHighlightStyles.test.tsx | 22 ++ .../util/useFilterFocusHighlightStyles.ts | 22 +- superset-frontend/src/types/Chart.ts | 2 + superset/connectors/sqla/models.py | 14 +- superset/dashboards/schemas.py | 1 + 21 files changed, 656 insertions(+), 38 deletions(-) create mode 100644 superset-frontend/src/dashboard/util/getRelatedCharts.test.ts create mode 100644 superset-frontend/src/dashboard/util/getRelatedCharts.ts diff --git a/docs/static/resources/openapi.json b/docs/static/resources/openapi.json index 43781ac9658b1..c2cadfd1f5767 100644 --- a/docs/static/resources/openapi.json +++ b/docs/static/resources/openapi.json @@ -3053,6 +3053,12 @@ }, "type": "array" }, + "column_names": { + "items": { + "type": "string" + }, + "type": "array" + }, "currency_formats": { "type": "object" }, diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts index d4170be17c623..86e7b1c04e518 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts +++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts @@ -83,6 +83,7 @@ export interface Dataset { owners?: Owner[]; filter_select?: boolean; filter_select_enabled?: boolean; + column_names?: string[]; } export interface ControlPanelState { diff --git a/superset-frontend/packages/superset-ui-core/src/query/types/Dashboard.ts b/superset-frontend/packages/superset-ui-core/src/query/types/Dashboard.ts index cb299c3ac96c4..ac4b19cae55ae 100644 --- a/superset-frontend/packages/superset-ui-core/src/query/types/Dashboard.ts +++ b/superset-frontend/packages/superset-ui-core/src/query/types/Dashboard.ts @@ -80,6 +80,24 @@ export type Filter = { description: string; }; +export type AppliedFilter = { + values: { + filters: Record[]; + } | null; +}; + +export type AppliedCrossFilterType = { + filterType: undefined; + targets: number[]; + scope: number[]; +} & AppliedFilter; + +export type AppliedNativeFilterType = { + filterType: 'filter_select'; + scope: number[]; + targets: Partial[]; +} & AppliedFilter; + export type FilterWithDataMask = Filter & { dataMask: DataMaskWithId }; export type Divider = Partial> & { @@ -89,6 +107,24 @@ export type Divider = Partial> & { type: typeof NativeFilterType.Divider; }; +export function isAppliedCrossFilterType( + filterElement: AppliedCrossFilterType | AppliedNativeFilterType | Filter, +): filterElement is AppliedCrossFilterType { + return ( + filterElement.filterType === undefined && + filterElement.hasOwnProperty('values') + ); +} + +export function isAppliedNativeFilterType( + filterElement: AppliedCrossFilterType | AppliedNativeFilterType | Filter, +): filterElement is AppliedNativeFilterType { + return ( + filterElement.filterType === 'filter_select' && + filterElement.hasOwnProperty('values') + ); +} + export function isNativeFilter( filterElement: Filter | Divider, ): filterElement is Filter { diff --git a/superset-frontend/packages/superset-ui-core/test/query/types/Dashboard.test.ts b/superset-frontend/packages/superset-ui-core/test/query/types/Dashboard.test.ts index 79d7980940867..c1c714395779a 100644 --- a/superset-frontend/packages/superset-ui-core/test/query/types/Dashboard.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/query/types/Dashboard.test.ts @@ -24,6 +24,10 @@ import { FilterWithDataMask, Divider, isNativeFilterWithDataMask, + isAppliedCrossFilterType, + isAppliedNativeFilterType, + AppliedCrossFilterType, + AppliedNativeFilterType, } from '@superset-ui/core'; const filter: Filter = { @@ -51,6 +55,20 @@ const filterDivider: Divider = { description: 'Divider description.', }; +const appliedCrossFilter: AppliedCrossFilterType = { + filterType: undefined, + targets: [1, 2], + scope: [1, 2], + values: null, +}; + +const appliedNativeFilter: AppliedNativeFilterType = { + filterType: 'filter_select', + scope: [1, 2], + targets: [{}], + values: null, +}; + test('filter type guard', () => { expect(isNativeFilter(filter)).toBeTruthy(); expect(isNativeFilter(filterWithDataMask)).toBeTruthy(); @@ -68,3 +86,13 @@ test('filter divider type guard', () => { expect(isFilterDivider(filterWithDataMask)).toBeFalsy(); expect(isFilterDivider(filterDivider)).toBeTruthy(); }); + +test('applied cross filter type guard', () => { + expect(isAppliedCrossFilterType(appliedCrossFilter)).toBeTruthy(); + expect(isAppliedCrossFilterType(appliedNativeFilter)).toBeFalsy(); +}); + +test('applied native filter type guard', () => { + expect(isAppliedNativeFilterType(appliedNativeFilter)).toBeTruthy(); + expect(isAppliedNativeFilterType(appliedCrossFilter)).toBeFalsy(); +}); diff --git a/superset-frontend/spec/fixtures/mockDashboardInfo.js b/superset-frontend/spec/fixtures/mockDashboardInfo.js index 2f747fd07b557..a046a554d0965 100644 --- a/superset-frontend/spec/fixtures/mockDashboardInfo.js +++ b/superset-frontend/spec/fixtures/mockDashboardInfo.js @@ -26,6 +26,7 @@ export default { { id: 'DefaultsID', filterType: 'filter_select', + chartsInScope: [], targets: [{}], cascadeParentIds: [], }, diff --git a/superset-frontend/spec/fixtures/mockNativeFilters.ts b/superset-frontend/spec/fixtures/mockNativeFilters.ts index 070f48ab06bd0..b83cdcc8dccdd 100644 --- a/superset-frontend/spec/fixtures/mockNativeFilters.ts +++ b/superset-frontend/spec/fixtures/mockNativeFilters.ts @@ -133,6 +133,7 @@ export const singleNativeFiltersState = { id: [NATIVE_FILTER_ID], name: 'eth', type: 'text', + filterType: 'filter_select', targets: [{ datasetId: 13, column: { name: 'ethnic_minority' } }], defaultDataMask: { filterState: { diff --git a/superset-frontend/src/dashboard/actions/dashboardState.js b/superset-frontend/src/dashboard/actions/dashboardState.js index 9b0c1818212a9..945dda32a319f 100644 --- a/superset-frontend/src/dashboard/actions/dashboardState.js +++ b/superset-frontend/src/dashboard/actions/dashboardState.js @@ -61,7 +61,7 @@ import { dashboardInfoChanged, SAVE_CHART_CONFIG_COMPLETE, } from './dashboardInfo'; -import { fetchDatasourceMetadata } from './datasources'; +import { fetchDatasourceMetadata, setDatasources } from './datasources'; import { updateDirectPathToFilter } from './dashboardFilters'; import { SET_FILTER_CONFIG_COMPLETE } from './nativeFilters'; import getOverwriteItems from '../util/getOverwriteItems'; @@ -341,6 +341,17 @@ export function saveDashboardRequest(data, id, saveType) { filterConfig: metadata.native_filter_configuration, }); } + + // fetch datasets to make sure they are up to date + SupersetClient.get({ + endpoint: `/api/v1/dashboard/${id}/datasets`, + headers: { 'Content-Type': 'application/json' }, + }).then(({ json }) => { + const datasources = json?.result ?? []; + if (datasources.length) { + dispatch(setDatasources(datasources)); + } + }); } if (lastModifiedTime) { dispatch(saveDashboardRequestSuccess(lastModifiedTime)); diff --git a/superset-frontend/src/dashboard/components/Dashboard.jsx b/superset-frontend/src/dashboard/components/Dashboard.jsx index 8cc0d8103026e..1953889c5d418 100644 --- a/superset-frontend/src/dashboard/components/Dashboard.jsx +++ b/superset-frontend/src/dashboard/components/Dashboard.jsx @@ -41,6 +41,7 @@ import { areObjectsEqual } from '../../reduxUtils'; import getLocationHash from '../util/getLocationHash'; import isDashboardEmpty from '../util/isDashboardEmpty'; import { getAffectedOwnDataCharts } from '../util/charts/getOwnDataCharts'; +import { getRelatedCharts } from '../util/getRelatedCharts'; const propTypes = { actions: PropTypes.shape({ @@ -211,9 +212,10 @@ class Dashboard extends PureComponent { applyFilters() { const { appliedFilters } = this; - const { activeFilters, ownDataCharts } = this.props; + const { activeFilters, ownDataCharts, datasources, slices } = this.props; // refresh charts if a filter was removed, added, or changed + const currFilterKeys = Object.keys(activeFilters); const appliedFilterKeys = Object.keys(appliedFilters); @@ -228,10 +230,24 @@ class Dashboard extends PureComponent { appliedFilterKeys.includes(filterKey) ) { // filterKey is removed? - affectedChartIds.push(...appliedFilters[filterKey].scope); + affectedChartIds.push( + ...getRelatedCharts( + appliedFilters, + activeFilters, + slices, + datasources, + )[filterKey], + ); } else if (!appliedFilterKeys.includes(filterKey)) { // filterKey is newly added? - affectedChartIds.push(...activeFilters[filterKey].scope); + affectedChartIds.push( + ...getRelatedCharts( + activeFilters, + appliedFilters, + slices, + datasources, + )[filterKey], + ); } else { // if filterKey changes value, // update charts in its scope @@ -244,7 +260,14 @@ class Dashboard extends PureComponent { }, ) ) { - affectedChartIds.push(...activeFilters[filterKey].scope); + affectedChartIds.push( + ...getRelatedCharts( + activeFilters, + appliedFilters, + slices, + datasources, + )[filterKey], + ); } // if filterKey changes scope, diff --git a/superset-frontend/src/dashboard/components/Dashboard.test.jsx b/superset-frontend/src/dashboard/components/Dashboard.test.jsx index b33fe9f6388c9..cd76787a21209 100644 --- a/superset-frontend/src/dashboard/components/Dashboard.test.jsx +++ b/superset-frontend/src/dashboard/components/Dashboard.test.jsx @@ -37,6 +37,9 @@ import { dashboardLayout } from 'spec/fixtures/mockDashboardLayout'; import dashboardState from 'spec/fixtures/mockDashboardState'; import { sliceEntitiesForChart as sliceEntities } from 'spec/fixtures/mockSliceEntities'; import { getAllActiveFilters } from 'src/dashboard/util/activeAllDashboardFilters'; +import { getRelatedCharts } from 'src/dashboard/util/getRelatedCharts'; + +jest.mock('src/dashboard/util/getRelatedCharts'); describe('Dashboard', () => { const props = { @@ -130,6 +133,7 @@ describe('Dashboard', () => { afterEach(() => { refreshSpy.restore(); + jest.clearAllMocks(); }); it('should not call refresh when is editMode', () => { @@ -153,6 +157,9 @@ describe('Dashboard', () => { }); it('should call refresh when native filters changed', () => { + getRelatedCharts.mockReturnValue({ + [NATIVE_FILTER_ID]: [230], + }); wrapper.setProps({ activeFilters: { ...OVERRIDE_FILTERS, @@ -170,11 +177,27 @@ describe('Dashboard', () => { [NATIVE_FILTER_ID]: { scope: [230], values: extraFormData, + filterType: 'filter_select', + targets: [ + { + datasetId: 13, + column: { + name: 'ethnic_minority', + }, + }, + ], }, }); }); it('should call refresh if a filter is added', () => { + getRelatedCharts.mockReturnValue({ + '1_region': [1], + '2_country_name': [1, 2], + '3_region': [1], + '3_country_name': [], + gender: [1], + }); const newFilter = { gender: { values: ['boy', 'girl'], scope: [1] }, }; @@ -186,6 +209,12 @@ describe('Dashboard', () => { }); it('should call refresh if a filter is removed', () => { + getRelatedCharts.mockReturnValue({ + '1_region': [1], + '2_country_name': [1, 2], + '3_region': [1], + '3_country_name': [], + }); wrapper.setProps({ activeFilters: {}, }); diff --git a/superset-frontend/src/dashboard/components/OverwriteConfirm/OverwriteConfirmModal.test.tsx b/superset-frontend/src/dashboard/components/OverwriteConfirm/OverwriteConfirmModal.test.tsx index 01e9e825bf222..5d93fd6900b04 100644 --- a/superset-frontend/src/dashboard/components/OverwriteConfirm/OverwriteConfirmModal.test.tsx +++ b/superset-frontend/src/dashboard/components/OverwriteConfirm/OverwriteConfirmModal.test.tsx @@ -51,6 +51,11 @@ test('renders diff viewer when it contains overwriteConfirmMetadata', async () = test('requests update dashboard api when save button is clicked', async () => { const updateDashboardEndpoint = `glob:*/api/v1/dashboard/${overwriteConfirmMetadata.dashboardId}`; + const fetchDatasetsEndpoint = `glob:*/api/v1/dashboard/${overwriteConfirmMetadata.dashboardId}/datasets`; + + // mock fetch datasets + fetchMock.get(fetchDatasetsEndpoint, []); + fetchMock.put(updateDashboardEndpoint, { id: overwriteConfirmMetadata.dashboardId, last_modified_time: +new Date(), diff --git a/superset-frontend/src/dashboard/fixtures/mockNativeFilters.ts b/superset-frontend/src/dashboard/fixtures/mockNativeFilters.ts index d1d37cbf6aecb..32f54cbe269db 100644 --- a/superset-frontend/src/dashboard/fixtures/mockNativeFilters.ts +++ b/superset-frontend/src/dashboard/fixtures/mockNativeFilters.ts @@ -39,6 +39,7 @@ export const nativeFiltersInfo: NativeFiltersState = { id: 'DefaultsID', name: 'test', filterType: 'filter_select', + chartsInScope: [], targets: [ { datasetId: 0, diff --git a/superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts b/superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts index f9e98e85365cb..3bde1d2e6f856 100644 --- a/superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts +++ b/superset-frontend/src/dashboard/util/activeAllDashboardFilters.ts @@ -54,9 +54,13 @@ export const getAllActiveFilters = ({ chartConfiguration?.[filterId]?.crossFilters?.chartsInScope ?? allSliceIds ?? []; + const filterType = nativeFilters?.[filterId]?.filterType; + const targets = nativeFilters?.[filterId]?.targets ?? scope; // Iterate over all roots to find all affected charts activeFilters[filterId] = { scope, + filterType, + targets, values: extraFormData, }; }); diff --git a/superset-frontend/src/dashboard/util/crossFilters.test.ts b/superset-frontend/src/dashboard/util/crossFilters.test.ts index e811856a4a39c..b88579cc843a0 100644 --- a/superset-frontend/src/dashboard/util/crossFilters.test.ts +++ b/superset-frontend/src/dashboard/util/crossFilters.test.ts @@ -294,14 +294,14 @@ test('Recalculate charts in global filter scope when charts change', () => { id: 2, crossFilters: { scope: 'global', - chartsInScope: [1], + chartsInScope: [1, 3], }, }, '3': { id: 3, crossFilters: { scope: 'global', - chartsInScope: [], + chartsInScope: [1, 2], }, }, }, diff --git a/superset-frontend/src/dashboard/util/crossFilters.ts b/superset-frontend/src/dashboard/util/crossFilters.ts index 880b826870a1a..903a1f74fbe55 100644 --- a/superset-frontend/src/dashboard/util/crossFilters.ts +++ b/superset-frontend/src/dashboard/util/crossFilters.ts @@ -52,20 +52,6 @@ export const getCrossFiltersConfiguration = ( return undefined; } - const chartsByDataSource: Record> = Object.values( - charts, - ).reduce((acc: Record>, chart) => { - if (!chart.form_data) { - return acc; - } - const { datasource } = chart.form_data; - if (!acc[datasource]) { - acc[datasource] = new Set(); - } - acc[datasource].add(chart.id); - return acc; - }, {}); - const globalChartConfiguration = metadata.global_chart_configuration?.scope ? { scope: metadata.global_chart_configuration.scope, @@ -111,13 +97,10 @@ export const getCrossFiltersConfiguration = ( }, }; } - const chartDataSource = charts[chartId].form_data.datasource; chartConfiguration[chartId].crossFilters.chartsInScope = isCrossFilterScopeGlobal(chartConfiguration[chartId].crossFilters.scope) ? globalChartConfiguration.chartsInScope.filter( - id => - id !== Number(chartId) && - chartsByDataSource[chartDataSource]?.has(id), + id => id !== Number(chartId), ) : getChartIdsInFilterScope( chartConfiguration[chartId].crossFilters.scope, diff --git a/superset-frontend/src/dashboard/util/getRelatedCharts.test.ts b/superset-frontend/src/dashboard/util/getRelatedCharts.test.ts new file mode 100644 index 0000000000000..94762e8f780dd --- /dev/null +++ b/superset-frontend/src/dashboard/util/getRelatedCharts.test.ts @@ -0,0 +1,254 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AppliedCrossFilterType, + DatasourceType, + Filter, + NativeFilterType, +} from '@superset-ui/core'; +import { DatasourcesState } from '../types'; +import { getRelatedCharts } from './getRelatedCharts'; + +const slices = { + '1': { datasource: 'ds1', slice_id: 1 }, + '2': { datasource: 'ds2', slice_id: 2 }, + '3': { datasource: 'ds1', slice_id: 3 }, +} as any; + +const datasources: DatasourcesState = { + ds1: { + uid: 'ds1', + datasource_name: 'ds1', + table_name: 'table1', + description: '', + id: 100, + columns: [{ column_name: 'column1' }, { column_name: 'column2' }], + column_names: ['column1', 'column2'], + column_types: [], + type: DatasourceType.Table, + metrics: [], + column_formats: {}, + currency_formats: {}, + verbose_map: {}, + main_dttm_col: '', + filter_select_enabled: true, + }, + ds2: { + uid: 'ds2', + datasource_name: 'ds2', + table_name: 'table2', + description: '', + id: 200, + columns: [{ column_name: 'column3' }, { column_name: 'column4' }], + column_names: ['column3', 'column4'], + column_types: [], + type: DatasourceType.Table, + metrics: [], + column_formats: {}, + currency_formats: {}, + verbose_map: {}, + main_dttm_col: '', + filter_select_enabled: true, + }, +}; + +test('Return chart ids matching the dataset id with native filter', () => { + const filters = { + filterKey1: { + filterType: 'filter_select', + chartsInScope: [1, 2], + scope: { + excluded: [], + rootPath: [], + }, + targets: [ + { + column: { name: 'column1' }, + datasetId: 100, + }, + ], + type: NativeFilterType.NativeFilter, + } as unknown as Filter, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + filterKey1: [1], + }); +}); + +test('Return chart ids matching the dataset id with cross filter', () => { + const filters = { + '3': { + filterType: undefined, + scope: [1, 2], + targets: [], + values: null, + } as AppliedCrossFilterType, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + '3': [1], + }); +}); + +test('Return chart ids matching the column name with native filter', () => { + const filters = { + filterKey1: { + filterType: 'filter_select', + chartsInScope: [1, 2], + scope: { + excluded: [], + rootPath: [], + }, + targets: [ + { + column: { name: 'column3' }, + datasetId: 999, + }, + ], + type: NativeFilterType.NativeFilter, + } as unknown as Filter, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + filterKey1: [2], + }); +}); + +test('Return chart ids matching the column name with cross filter', () => { + const filters = { + '1': { + filterType: undefined, + scope: [1, 2], + targets: [], + values: { + filters: [{ col: 'column3' }], + }, + } as AppliedCrossFilterType, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + '1': [2], + }); +}); + +test('Return chart ids when column display name matches with native filter', () => { + const filters = { + filterKey1: { + filterType: 'filter_select', + chartsInScope: [1, 2], + scope: { + excluded: [], + rootPath: [], + }, + targets: [ + { + column: { name: 'column4', displayName: 'column4' }, + datasetId: 999, + }, + ], + type: NativeFilterType.NativeFilter, + } as unknown as Filter, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + filterKey1: [2], + }); +}); + +test('Return chart ids when column display name matches with cross filter', () => { + const filters = { + '1': { + filterType: undefined, + scope: [1, 2], + targets: [], + values: { + filters: [{ col: 'column4' }], + }, + } as AppliedCrossFilterType, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + '1': [2], + }); +}); + +test('Return scope when filterType is not filter_select', () => { + const filters = { + filterKey1: { + filterType: 'filter_time', + chartsInScope: [3, 4], + } as Filter, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + filterKey1: [3, 4], + }); +}); + +test('Return an empty array if no matching charts found with native filter', () => { + const filters = { + filterKey1: { + filterType: 'filter_select', + chartsInScope: [1, 2], + scope: { + excluded: [], + rootPath: [], + }, + targets: [ + { + column: { name: 'nonexistent_column' }, + datasetId: 300, + }, + ], + type: NativeFilterType.NativeFilter, + } as unknown as Filter, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + filterKey1: [], + }); +}); + +test('Return an empty array if no matching charts found with cross filter', () => { + const filters = { + '1': { + filterType: undefined, + scope: [1, 2], + targets: [], + values: { + filters: [{ col: 'nonexistent_column' }], + }, + } as AppliedCrossFilterType, + }; + + const result = getRelatedCharts(filters, null, slices, datasources); + expect(result).toEqual({ + '1': [], + }); +}); diff --git a/superset-frontend/src/dashboard/util/getRelatedCharts.ts b/superset-frontend/src/dashboard/util/getRelatedCharts.ts new file mode 100644 index 0000000000000..aba56ba3b6c19 --- /dev/null +++ b/superset-frontend/src/dashboard/util/getRelatedCharts.ts @@ -0,0 +1,200 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + AppliedCrossFilterType, + AppliedNativeFilterType, + ensureIsArray, + Filter, + isAppliedCrossFilterType, + isAppliedNativeFilterType, + isNativeFilter, +} from '@superset-ui/core'; +import { Slice } from 'src/types/Chart'; +import { DatasourcesState } from '../types'; + +function checkForExpression(formData?: Record) { + const groupby = ensureIsArray(formData?.groupby) ?? []; + const allColumns = ensureIsArray(formData?.all_columns) ?? []; + const checkColumns = groupby.concat(allColumns); + return checkColumns.some( + (col: string | Record) => + typeof col !== 'string' && col.expressionType !== undefined, + ); +} + +function getRelatedChartsForSelectFilter( + nativeFilter: AppliedNativeFilterType | Filter, + slices: Record, + chartsInScope: number[], + datasources: DatasourcesState, +) { + return Object.values(slices) + .filter(slice => { + const { datasource, slice_id } = slice; + // not in scope, ignore + if (!chartsInScope.includes(slice_id)) return false; + + const chartDatasource = datasource + ? datasources[datasource] + : Object.values(datasources).find(ds => ds.id === slice.datasource_id); + + const { column, datasetId } = nativeFilter.targets?.[0] ?? {}; + const datasourceColumnNames = chartDatasource?.column_names ?? []; + + // same datasource, always apply + if (chartDatasource?.id === datasetId) return true; + + // let backend deal with adhoc columns and jinja + const hasSqlExpression = checkForExpression(slice.form_data); + if (hasSqlExpression) { + return true; + } + + return datasourceColumnNames.some( + col => col === column?.name || col === column?.displayName, + ); + }) + .map(slice => slice.slice_id); +} +function getRelatedChartsForCrossFilter( + filterKey: string, + crossFilter: AppliedCrossFilterType, + slices: Record, + scope: number[], + datasources: DatasourcesState, +): number[] { + const sourceSlice = slices[filterKey]; + const filters = crossFilter?.values?.filters ?? []; + + if (!sourceSlice) return []; + + const sourceDatasource = sourceSlice.datasource + ? datasources[sourceSlice.datasource] + : Object.values(datasources).find( + ds => ds.id === sourceSlice.datasource_id, + ); + + return Object.values(slices) + .filter(slice => { + // cross-filter emitter + if (slice.slice_id === Number(filterKey)) return false; + // not in scope, ignore + if (!scope.includes(slice.slice_id)) return false; + + const targetDatasource = slice.datasource + ? datasources[slice.datasource] + : Object.values(datasources).find(ds => ds.id === slice.datasource_id); + + // same datasource, always apply + if (targetDatasource === sourceDatasource) return true; + + const targetColumnNames = targetDatasource?.column_names ?? []; + + // let backend deal with adhoc columns and jinja + const hasSqlExpression = checkForExpression(slice.form_data); + if (hasSqlExpression) { + return true; + } + + for (const filter of filters) { + // let backend deal with adhoc columns + if ( + typeof filter.col !== 'string' && + filter.col.expressionType !== undefined + ) { + return true; + } + // shared column names, different datasources, apply filter + if (targetColumnNames.includes(filter.col)) return true; + } + + return false; + }) + .map(slice => slice.slice_id); +} + +export function getRelatedCharts( + filters: Record< + string, + AppliedNativeFilterType | AppliedCrossFilterType | Filter + >, + checkFilters: Record< + string, + AppliedNativeFilterType | AppliedCrossFilterType | Filter + > | null, + slices: Record, + datasources: DatasourcesState, +) { + const related = Object.entries(filters).reduce((acc, [filterKey, filter]) => { + const isCrossFilter = + Object.keys(slices).includes(filterKey) && + isAppliedCrossFilterType(filter); + + const chartsInScope = Array.isArray(filter.scope) + ? filter.scope + : ((filter as Filter).chartsInScope ?? []); + + if (isCrossFilter) { + const checkFilter = checkFilters?.[filterKey] as AppliedCrossFilterType; + const crossFilter = filter as AppliedCrossFilterType; + const wasRemoved = !!( + ((filter.values && filter.values.filters === undefined) || + filter.values?.filters?.length === 0) && + checkFilter?.values?.filters?.length + ); + const actualCrossFilter = wasRemoved ? checkFilter : crossFilter; + + return { + ...acc, + [filterKey]: getRelatedChartsForCrossFilter( + filterKey, + actualCrossFilter, + slices, + chartsInScope, + datasources, + ), + }; + } + + const nativeFilter = filter as AppliedNativeFilterType | Filter; + // on highlight, a standard native filter is passed + // on apply, an applied native filter is passed + if ( + isAppliedNativeFilterType(nativeFilter) || + isNativeFilter(nativeFilter) + ) { + return { + ...acc, + [filterKey]: getRelatedChartsForSelectFilter( + nativeFilter, + slices, + chartsInScope, + datasources, + ), + }; + } + return { + ...acc, + [filterKey]: chartsInScope, + }; + }, {}); + + return related; +} diff --git a/superset-frontend/src/dashboard/util/useFilterFocusHighlightStyles.test.tsx b/superset-frontend/src/dashboard/util/useFilterFocusHighlightStyles.test.tsx index d3010376da210..ca19c63d51642 100644 --- a/superset-frontend/src/dashboard/util/useFilterFocusHighlightStyles.test.tsx +++ b/superset-frontend/src/dashboard/util/useFilterFocusHighlightStyles.test.tsx @@ -24,6 +24,9 @@ import reducerIndex from 'spec/helpers/reducerIndex'; import { screen, render } from 'spec/helpers/testing-library'; import { initialState } from 'src/SqlLab/fixtures'; import useFilterFocusHighlightStyles from './useFilterFocusHighlightStyles'; +import { getRelatedCharts } from './getRelatedCharts'; + +jest.mock('./getRelatedCharts'); const TestComponent = ({ chartId }: { chartId: number }) => { const styles = useFilterFocusHighlightStyles(chartId); @@ -38,6 +41,7 @@ describe('useFilterFocusHighlightStyles', () => { { ...mockState, ...(initialState as any), ...customState }, compose(applyMiddleware(thunk)), ); + const mockGetRelatedCharts = getRelatedCharts as jest.Mock; const renderWrapper = (chartId: number, store = createMockStore()) => render(, { @@ -57,6 +61,9 @@ describe('useFilterFocusHighlightStyles', () => { }); it('should return unfocused styles if chart is not in scope of focused native filter', async () => { + mockGetRelatedCharts.mockReturnValue({ + 'test-filter': [], + }); const store = createMockStore({ nativeFilters: { focusedFilterId: 'test-filter', @@ -76,6 +83,9 @@ describe('useFilterFocusHighlightStyles', () => { }); it('should return unfocused styles if chart is not in scope of hovered native filter', async () => { + mockGetRelatedCharts.mockReturnValue({ + 'test-filter': [], + }); const store = createMockStore({ nativeFilters: { hoveredFilterId: 'test-filter', @@ -96,6 +106,9 @@ describe('useFilterFocusHighlightStyles', () => { it('should return focused styles if chart is in scope of focused native filter', async () => { const chartId = 18; + mockGetRelatedCharts.mockReturnValue({ + testFilter: [chartId], + }); const store = createMockStore({ nativeFilters: { focusedFilterId: 'testFilter', @@ -116,6 +129,9 @@ describe('useFilterFocusHighlightStyles', () => { it('should return focused styles if chart is in scope of hovered native filter', async () => { const chartId = 18; + mockGetRelatedCharts.mockReturnValue({ + testFilter: [chartId], + }); const store = createMockStore({ nativeFilters: { hoveredFilterId: 'testFilter', @@ -136,6 +152,9 @@ describe('useFilterFocusHighlightStyles', () => { it('should return unfocused styles if focusedFilterField is targeting a different chart', async () => { const chartId = 18; + mockGetRelatedCharts.mockReturnValue({ + testFilter: [], + }); const store = createMockStore({ dashboardState: { focusedFilterField: { @@ -159,6 +178,9 @@ describe('useFilterFocusHighlightStyles', () => { it('should return focused styles if focusedFilterField chart equals our own', async () => { const chartId = 18; + mockGetRelatedCharts.mockReturnValue({ + testFilter: [chartId], + }); const store = createMockStore({ dashboardState: { focusedFilterField: { diff --git a/superset-frontend/src/dashboard/util/useFilterFocusHighlightStyles.ts b/superset-frontend/src/dashboard/util/useFilterFocusHighlightStyles.ts index f1f428240c169..74d31f60d6567 100644 --- a/superset-frontend/src/dashboard/util/useFilterFocusHighlightStyles.ts +++ b/superset-frontend/src/dashboard/util/useFilterFocusHighlightStyles.ts @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -import { useTheme } from '@superset-ui/core'; +import { Filter, useTheme } from '@superset-ui/core'; import { useSelector } from 'react-redux'; import { getChartIdsInFilterScope } from 'src/dashboard/util/activeDashboardFilters'; import { DashboardState, RootState } from 'src/dashboard/types'; +import { getRelatedCharts } from './getRelatedCharts'; const selectFocusedFilterScope = ( dashboardState: DashboardState, @@ -41,6 +42,7 @@ const useFilterFocusHighlightStyles = (chartId: number) => { const dashboardState = useSelector( (state: RootState) => state.dashboardState, ); + const dashboardFilters = useSelector( (state: RootState) => state.dashboardFilters, ); @@ -49,6 +51,18 @@ const useFilterFocusHighlightStyles = (chartId: number) => { dashboardFilters, ); + const datasources = + useSelector((state: RootState) => state.datasources) || {}; + const slices = + useSelector((state: RootState) => state.sliceEntities.slices) || {}; + + const relatedCharts = getRelatedCharts( + nativeFilters.filters as Record, + null, + slices, + datasources, + ); + const highlightedFilterId = nativeFilters?.focusedFilterId || nativeFilters?.hoveredFilterId; if (!(focusedFilterScope || highlightedFilterId)) { @@ -69,11 +83,7 @@ const useFilterFocusHighlightStyles = (chartId: number) => { }; if (highlightedFilterId) { - if ( - nativeFilters.filters[highlightedFilterId]?.chartsInScope?.includes( - chartId, - ) - ) { + if (relatedCharts[highlightedFilterId]?.includes(chartId)) { return focusedChartStyles; } } else if ( diff --git a/superset-frontend/src/types/Chart.ts b/superset-frontend/src/types/Chart.ts index f26525cd33580..b7c439cb211f0 100644 --- a/superset-frontend/src/types/Chart.ts +++ b/superset-frontend/src/types/Chart.ts @@ -74,6 +74,8 @@ export type Slice = { query_context?: object; is_managed_externally: boolean; owners?: number[]; + datasource?: string; + datasource_id?: number; }; export default Chart; diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 82980cef161d8..e8aa0d705b8f8 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -489,6 +489,11 @@ def data_for_slices( # pylint: disable=too-many-locals del data["description"] data.update({"metrics": filtered_metrics}) data.update({"columns": filtered_columns}) + + all_columns = { + column_["column_name"]: column_["verbose_name"] or column_["column_name"] + for column_ in filtered_columns + } verbose_map = {"__timestamp": "Time"} verbose_map.update( { @@ -496,14 +501,9 @@ def data_for_slices( # pylint: disable=too-many-locals for metric in filtered_metrics } ) - verbose_map.update( - { - column_["column_name"]: column_["verbose_name"] - or column_["column_name"] - for column_ in filtered_columns - } - ) + verbose_map.update(all_columns) data["verbose_map"] = verbose_map + data["column_names"] = set(all_columns.values()) | set(self.column_names) return data diff --git a/superset/dashboards/schemas.py b/superset/dashboards/schemas.py index b0a47aba414ce..d63e79336c377 100644 --- a/superset/dashboards/schemas.py +++ b/superset/dashboards/schemas.py @@ -262,6 +262,7 @@ class DashboardDatasetSchema(Schema): owners = fields.List(fields.Dict()) columns = fields.List(fields.Dict()) column_types = fields.List(fields.Int()) + column_names = fields.List(fields.Str()) metrics = fields.List(fields.Dict()) order_by_choices = fields.List(fields.List(fields.Str())) verbose_map = fields.Dict(fields.Str(), fields.Str()) From 74b63a4ba4e6f4f51796331a7bdb1eed68ab411e Mon Sep 17 00:00:00 2001 From: Sam Firke Date: Tue, 15 Oct 2024 19:31:56 -0400 Subject: [PATCH 20/23] fix(docs): leading whitespace line is causing page title and header to be malformed (#30616) --- docs/docs/configuration/networking-settings.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/docs/configuration/networking-settings.mdx b/docs/docs/configuration/networking-settings.mdx index 611b44cf0abcb..0e1f3c969f6d8 100644 --- a/docs/docs/configuration/networking-settings.mdx +++ b/docs/docs/configuration/networking-settings.mdx @@ -1,4 +1,3 @@ - --- title: Network and Security Settings sidebar_position: 7 From 53a121d9e1339f61d7495d710c699cf4c3a8e54a Mon Sep 17 00:00:00 2001 From: Sam Firke Date: Tue, 15 Oct 2024 19:32:24 -0400 Subject: [PATCH 21/23] fix(docs): address two linkinator failures (#30617) --- RELEASING/release-notes-4-1/README.md | 2 +- RESOURCES/INTHEWILD.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/RELEASING/release-notes-4-1/README.md b/RELEASING/release-notes-4-1/README.md index d808fabad9361..9c7b387198bee 100644 --- a/RELEASING/release-notes-4-1/README.md +++ b/RELEASING/release-notes-4-1/README.md @@ -137,4 +137,4 @@ There is now a [metadata bar](https://github.com/apache/superset/pull/27857) add ## Change to Docker image builds -Starting in 4.1.0, the release's docker image does not ship with drivers needed to operate Superset. Users may need to install a driver for their metadata database (MySQL or Postgres) as well as the driver for their data warehouse. This is a result of changes to the `lean` docker image that official releases come from; see [Docker Build Presets](/docs/installation/docker-builds/#build-presets) for more details. +Starting in 4.1.0, the release's docker image does not ship with drivers needed to operate Superset. Users may need to install a driver for their metadata database (MySQL or Postgres) as well as the driver for their data warehouse. This is a result of changes to the `lean` docker image that official releases come from; see [Docker Build Presets](/docs/installation/docker-builds#build-presets) for more details. diff --git a/RESOURCES/INTHEWILD.md b/RESOURCES/INTHEWILD.md index 6f9d5f0a6f307..777fb9ee923bc 100644 --- a/RESOURCES/INTHEWILD.md +++ b/RESOURCES/INTHEWILD.md @@ -80,7 +80,6 @@ Join our growing community! - [Caizin](https://caizin.com/) [@tejaskatariya] - [Careem](https://www.careem.com/) [@SamraHanifCareem] - [Cloudsmith](https://cloudsmith.io) [@alancarson] -- [CnOvit](https://www.cnovit.com/) [@xieshaohu] - [Cyberhaven](https://www.cyberhaven.com/) [@toliver-ch] - [Deepomatic](https://deepomatic.com/) [@Zanoellia] - [Dial Once](https://www.dial-once.com/) From c8edd1fb2565e255b00d79769873fad213fb7a05 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:07:12 -0300 Subject: [PATCH 22/23] fix: First item hovered on stacked bar (#30628) --- .../plugin-chart-echarts/src/Timeseries/transformProps.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts index bed39c7bc5180..c0da444bfe802 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts @@ -590,7 +590,7 @@ export default function transformProps( }); if (stack) { rows.reverse(); - if (focusedRow) { + if (focusedRow !== undefined) { focusedRow = rows.length - focusedRow - 1; } } From bad48d072224a4cc47a263a71aef02ba8f70e1e5 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Wed, 16 Oct 2024 15:14:11 -0300 Subject: [PATCH 23/23] fix: Module is not defined in Partition chart (#30626) --- superset-frontend/package-lock.json | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index e08995b929eaf..c19eafc75c2c4 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -21314,6 +21314,15 @@ "version": "0.2.2", "license": "BSD-3-Clause" }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/d3-interpolate": { "version": "3.0.1", "license": "ISC", @@ -57601,13 +57610,6 @@ "react-dom": "^16.13.1" } }, - "plugins/legacy-plugin-chart-partition/node_modules/d3-hierarchy": { - "version": "3.1.2", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "plugins/legacy-plugin-chart-rose": { "name": "@superset-ui/legacy-plugin-chart-rose", "version": "0.18.25", @@ -68285,11 +68287,6 @@ "d3": "^3.5.17", "d3-hierarchy": "^3.1.2", "prop-types": "^15.8.1" - }, - "dependencies": { - "d3-hierarchy": { - "version": "3.1.2" - } } }, "@superset-ui/legacy-plugin-chart-rose": { @@ -74917,6 +74914,11 @@ "d3-hexbin": { "version": "0.2.2" }, + "d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==" + }, "d3-interpolate": { "version": "3.0.1", "requires": {